检查一个二叉树是否平衡的算法分析与C++实现

今天面试一个实习生,就想既然是未出校园,那就出一个比较基础的题吧,没想到答的并不如人意,对于树的操作完全不熟悉,因此此题算是未作答。原来我想看一下他分析问题的思路,优化代码的能力。接下来会把最近半年我出的面试题整理出来,以来share给其它同事,而来算是自己校园记忆的一个总结,毕竟自己在项目中已经很久未用到这些知识。其实很多题目都是来源于CareerCup.com。这上面汇集了许多IT名企的面试笔试题目,非常值得找工作的人学习。

言归正传,什么是二叉树是否平衡的定义,如果面试者不知道,那肯定要提出来,而不是简简单单说我对树不熟悉,或者找其他更多更多的理由。

其实可以根据平衡的定义,直接递归访问整棵树,计算子树的高度。

struct TreeNode{
	TreeNode *leftChild;
	TreeNode *rightChild;
	int data;
};

int getHeight(const TreeNode* root){
	if( root == nullptr){
		return 0;
	}

	return max(getHeight(root->leftChild), getHeight(root->rightChild)) + 1;
}

bool isBalanced(const TreeNode* root){
	if( root == nullptr){
		return true;
	}

	int heightDiff = abs(getHeight(root->leftChild) - getHeight(root->rightChild));
	if( heightDiff > 1){
		return false;
	}
	else{
		return isBalanced(root->leftChild) && isBalanced(root->rightChild);
	}
}

如果开始能给出这个解法那是可以接受的。但是,由于同一个node的高度会被重复计算,因此效率不高。算法复杂度是O(n*logn)。接下来,我们要改进这个算法,使得子树的高度不再重复计算:我们通过删减重复的getHeight(const TreeNode*)调用。其实getHeight不单可以计算子树的高度,其实还可以判断子树是否的平衡的,如果不平衡怎么办?直接返回-1。那该递归调用就可以结束了。

因此,改进的算法就是从root开始递归检查每个子树的高度,如果子树是平衡的,那么就返回子树的高度,否则返回-1:递归结束,树是不平衡的。

int checkHeight(const TreeNode* root){
	if( root == nullptr){
		return 0;
	}
	// check the left subtree is balanced or not.
	int leftHeight = checkHeight(root->leftChild);
	if( leftHeight == -1 ){
		return -1;
	}

	// check the right subtree is balanced or not.
	int rightHeight = checkHeight(root->rightChild);
	if( rightHeight == -1){
		return -1;
	}

	// check the current tree is balanced or not.
	int diff = leftHeight - rightHeight;
	if( abs(diff) > 1){
		return -1;
	}
	else{
		// return the tree height.
		return max(leftHeight, rightHeight) + 1;
	}
}
bool isBalanced(const TreeNode* root){
    return ( checkHeight(root) == -1 )? false:true;
}

由于每个node只会访问一次,因此算法时间复杂度为O(n)。但是需要额外的O(logn)的空间。

时间: 2024-07-29 01:24:42

检查一个二叉树是否平衡的算法分析与C++实现的相关文章

求助!一个二叉树程序创建和遍历的程序

问题描述 求助!一个二叉树程序创建和遍历的程序 #include #include typedef char ElementType; typedef struct BiNode{ ElementType data; struct BiNode * lchild; struct BiNode * rchild; }BiNode; void CreatBiTree2(BiNode * T); void PreTraverBiTree(BiNode const * T); int main() {

《Python Cookbook(第2版)中文版》——1.11 检查一个字符串是文本还是二进制

1.11 检查一个字符串是文本还是二进制 任务 在Python中,普通字符串既可以容纳文本,也可以容纳任意的字节,现在需要探知(当然,完全是启发式的试探:对于这个问题并没有什么精准的算法)一个字符串中的数据究竟是文本还是二进制. 解决方案 我们采取Perl的判定方法,如果字符串中包含了空值或者其中有超过30%的字符的高位被置1(意味着该字符的码值大于126)或是奇怪的控制码,我们就认为这段数据是二进制数据.我们得自己编写代码,其优点是对于特殊的程序需求,我们随时可以调整这种启发式的探知方式: f

c-请大家帮我检查一个简单的C程序

问题描述 请大家帮我检查一个简单的C程序 代码如下:#include #include #include #define maxn 99struct student{ char name[20]; int grade;} stu[maxn];int cmp(const void*a const void*b){ return ((struct student*)a)->grade - ((struct student*)b)->grade;}int main(void){ puts("

C++语言如何用数组实现一个二叉树?

问题描述 C++语言如何用数组实现一个二叉树? 提示,二叉树的第n层可以用数组的第2^(n-1)~2^n-1表示.定义一个二叉树,并且实现对它的遍历. 解决方案 struct node { int l,r; }; struct node tree[100]; int path[100]; int ans; void init() { int i; ans = 0; for(i = 0 ; i < 100 ; i ++ ) tree[i].l = tree[i].r = -1,path[i] =

如何判断一个树是不是另外一个二叉树的子树呢?

问题描述 如何判断一个树是不是另外一个二叉树的子树呢? 请教大神们一个数据结构的问题,才学,琢磨很久没想出来 解决方案 //判断root2是不是root1开头的子结构 boolIsSubTree(BiTreeNode *root1BiTreeNode *root2) { //先判断root2 if(root2==NULL) return true; if(root1==NULL) return false; if(root1->data!=root2->data) return false;

php-如何检查一个变量是否被设置,并且值为NULL

问题描述 如何检查一个变量是否被设置,并且值为NULL 最近有一个小问题,就是如何在php中检查一个变量是否被设置并且值为null,看看大家都有什么好的解决方案?谢谢~~ 解决方案 啥意思,你判断它是不是等于null不行吗? 解决方案二: 你的意思时这个变量是否有初始化?如果你判断不清的话,在最开始的时候直接做一个初始化不就好了么?然后初始化成什么,你就判断什么. 解决方案三: 你的意思是想问,怎么区分这个字段值是null还是给他赋值成null么?这个貌似没办法判断吧~ 解决方案四: <?php

判断二叉树是否平衡、是否完全二叉树、是否二叉排序树

1.判断二叉树是否平衡 //求树的高度 int TreeDepth(Node* t) { int hl,hr,h; if(t != NULL) { hl = TreeDepth(t->left); hr = TreeDepth(t->right); h = hl>hr? hl:hr; return h+1; } return 0; } //判断二叉树是否平衡 int isBalanced(Node* t) { if(t==NULL) return 1; int leftDepth = T

python新手求助-Python3.x 检查一个类的基类

问题描述 Python3.x 检查一个类的基类 Python基础教程P123页检查类SPAMFilter的基类是这样做的 SPAMFilter._bases_ 但是我没找到这个属性,怎么回事?Python3.x取消了吗? 解决方案 查看u 一下官方文档就知道了.

在线求助,输入一个二叉树,如何从叶子节点向上逐层打印

问题描述 在线求助,输入一个二叉树,如何从叶子节点向上逐层打印二叉树的形式如下:ABCDEFG程序打印出,DEFGBCA用java如何实现,请高手指点一下,谢谢! 解决方案 解决方案二:先层次遍历,压入到堆栈或者向量什么的都可以...解决方案三:楼上的有没有代码示例呀?解决方案四:importjava.util.ArrayList;importjava.util.List;publicclassTest{publicstaticvoidmain(String[]args){//组装一颗树Node