判断二叉数是否是平衡树

本文探讨了如何确定一棵二叉树是否为高度平衡的树,并提供了两种算法实现方案。第一种方法通过递归计算每个节点的左右子树深度来进行判断,第二种方法则在计算深度的同时完成平衡性的判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

Solutions:

可以写一个函数求一棵二叉树的深度。每次判断一个节点时就将分别求其左右子树的深度,深度相减判断。

<pre name="code" class="cpp">int getHeight(TreeNode *root) {
	if(root == NULL){
		return 0;
	}
	int l=getHeight(root->left);
	int r=getHeight(root->right);
	return 1 + (l>r?l:r);
}

但这样明显有重复运算。

可以边计算深度边判断。

class Solution {
public:
	bool judgeBalance(TreeNode *root, int &height) {
		if(root == NULL) {
			height=0;
			return true;
		}
		int rh=0, lh=0;
		bool l=judgeBalance(root->left, lh);
		bool r=judgeBalance(root->right, rh);
		if(l && r) {
			if(rh-lh<-1 || rh-lh >1) {
				return false;
			}
			height=1+ (rh>lh?rh:lh);
		}
		else {
			return false;
		}
	}
    bool isBalanced(TreeNode* root) {
		int h=0;
		return judgeBalance(root, h);
    }
};

转自http://blog.sina.com.cn/s/blog_819d2f490100sz7e.html的方法:

我们再回过头看平衡二叉树的定义,即平衡二叉树需要满足的条件:
(1)空树:depth = 0
(2)不为空树,左右子树都为平衡二叉树,且左右子树高度差的绝对值小于等于1

我们是不是可以用高度来判断一棵二叉树是不是平衡二叉树呢?
    如果高度 >= 0,则是平衡二叉树;
    如果高度 < 0,则不是平衡二叉树。

class Solution {
public:
	int isBalanced(TreeNode *root) {
		if(root == NULL) {
			return 0;
		}
		int l=isBalanced(root->left);
		int r=isBalanced(root->right);
		if(l >= 0 && r>=0) {
			if(l-r <= -1 || l-r >= 1) {
				return l>=r?(l+1):(r+1);
			}
		}
		return -1;
	}
};



<think>我们被要求提供C语言代码来判断一棵二叉树是否为平衡二叉树平衡二叉树的定义是:每个节点的左右子树高度差不超过1,并且左右子树也都是平衡二叉树。 根据引用[1]和引用[2]提供的思路,我们可以采用递归的方法。在递归计算树的高度的同时,检查每个节点的左右子树高度差是否超过1。如果超过1,则设置一个标记表示不平衡。 我们可以设计一个函,它返回当前节点的高度,并且在递归过程中检查平衡性。如果发现不平衡,则通过一个全局变量或者通过指针传递的参来记录不平衡的状态。 但是,使用全局变量并不是一个很好的做法,因为它使得函不可重入。我们可以通过返回一个特殊值来表示不平衡(比如返回-1表示子树不平衡),或者通过参来传递平衡状态。 这里我们采用两种方法: 方法一:使用一个全局变量(如引用[1]中的BalanceTrue)来记录是否平衡。这种方法简单,但全局变量有副作用。 方法二:不使用全局变量,而是通过函返回值同时传递高度和平衡信息。我们可以让函平衡时返回树的高度,不平衡时返回-1(或者一个特殊值)。这样,我们可以通过检查返回值是否为-1来判断是否平衡。 我们选择方法二,因为它避免了全局变量,符合结构化编程的思想。 设计函: int isBalancedHelper(TreeNode *root) 如果root为空,返回0(空树高度为0,且平衡)。 否则,递归计算左子树的高度leftHeight,如果leftHeight为-1,表示左子树不平衡,则直接返回-1。 同样递归计算右子树的高度rightHeight,如果rightHeight为-1,表示右子树不平衡,则直接返回-1。 然后,检查左右子树的高度差绝对值是否大于1,如果大于1,返回-1(表示当前节点为根的树不平衡)。 否则,返回当前树的高度(max(leftHeight, rightHeight)+1)。 最后,我们用一个包装函: bool isBalanced(TreeNode *root) 调用isBalancedHelper(root),如果返回-1,则不平衡(返回false),否则平衡(返回true)。 注意:这种自底向上的递归方法,每个节点只访问一次,时间复杂度为O(n)。 下面我们根据引用[1]和引用[2]提供的代码风格,以及上述思路,写出C语言代码。 我们定义二叉树节点结构体(如引用[1]所示): typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; 然后实现辅助函和主判断。 注意:引用[1]中的代码使用了全局变量,而我们这里不使用全局变量,而是通过返回值传递状态。 代码实现:</think>### C语言实现平衡二叉树判断(递归法) 以下是判断二叉树是否为平衡二叉树的完整C语言代码实现。平衡二叉树的定义:每个节点的左右子树高度差不超过1,且所有子树也满足该条件[^1][^2]。 ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> // 二叉树节点结构 typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; // 计算树的高度(递归) int height(TreeNode* root) { if (root == NULL) return 0; int leftHeight = height(root->left); int rightHeight = height(root->right); return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1; } // 判断平衡二叉树的主函(递归) bool isBalanced(TreeNode* root) { if (root == NULL) return true; // 空树是平衡的 // 计算左右子树高度差 int diff = abs(height(root->left) - height(root->right)); // 检查当前节点和递归检查子树 return (diff <= 1) && isBalanced(root->left) && isBalanced(root->right); } // 辅助函:创建新节点 TreeNode* createNode(int data) { TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode)); newNode->data = data; newNode->left = newNode->right = NULL; return newNode; } int main() { /* 测试用例:构建示例二叉树 1 / \ 2 3 / \ \ 4 5 6 */ TreeNode* root = createNode(1); root->left = createNode(2); root->right = createNode(3); root->left->left = createNode(4); root->left->right = createNode(5); root->right->right = createNode(6); // 判断并输出结果 if (isBalanced(root)) printf("该二叉树平衡二叉树\n"); else printf("该二叉树不是平衡二叉树\n"); /* 释放内存(实际应用中需实现完整的内存管理)*/ return 0; } ``` #### 代码解析: 1. **据结构**: - `TreeNode`结构体包含节点据和左右子树指针[^1][^4] 2. **核心函**: - `height()`:递归计算树的高度(时间复杂度$O(n)$) - `isBalanced()`:判断平衡性的主函 - 检查当前节点左右子树高度差$|h_{left} - h_{right}| \leq 1$ - 递归检查左右子树是否平衡 3. **算法特点**: - 时间复杂度:$O(n^2)$(最坏情况) - 空间复杂度:$O(h)$($h$为树高,递归栈空间)[^2] - 自顶向下递归:符合平衡二叉树的递归定义 #### 优化方向: 对于大规模树,可优化为自底向上递归(时间复杂度$O(n)$): ```c int checkHeight(TreeNode* root) { if (!root) return 0; int leftHeight = checkHeight(root->left); if (leftHeight == -1) return -1; int rightHeight = checkHeight(root->right); if (rightHeight == -1) return -1; if (abs(leftHeight - rightHeight) > 1) return -1; return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1; } bool isBalancedOptimized(TreeNode* root) { return checkHeight(root) != -1; } ``` #### 测试用例设计建议: 1. 空树(平衡) 2. 单节点树(平衡) 3. 完全平衡树平衡) 4. 左/右斜树(不平衡) 5. 最小不平衡子树(如[1,2,3,4]线性树) > 注意:实际应用中需添加内存管理代码防止泄漏[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值