判断树是否为平衡二叉树

平衡二叉树深度与判断方法详解

来自剑指offer

求树的深度

用递归做很简单,只要知道递归出口语句的别写错。

  1. struct BinaryTreeNode  
  2. {  
  3.     int m_Value;  
  4.     BinaryTreeNode* m_pLeft;  
  5.     BinaryTreeNode* m_pRight;  
  6. };  
  7.   
  8. int TreeDepth(BinaryTreeNode* pRoot)  
  9. {  
  10.     if (pRoot == NULL)  
  11.         return 0;  
  12.   
  13.     int nLeftDepth = TreeDepth(pRoot->m_pLeft);  
  14.     int nRightDepth = TreeDepth(pRoot->m_pRight);  
  15.   
  16.     return (nLeftDepth>nRightDepth)?(nLeftDepth+1):(nRightDepth+1);  
  17. }  

判断该树是否为平衡二叉树

方法一:调用上述函数求每个节点的左右孩子深度

  1. bool IsBalanced(BinaryTreeNode* pRoot)  
  2. {  
  3.     if(pRoot== NULL)  
  4.         return true;  
  5.   
  6.     int nLeftDepth = TreeDepth(pRoot->m_pLeft);  
  7.     int nRightDepth = TreeDepth(pRoot->m_pRight);  
  8.     int diff = nRightDepth-nLeftDepth;  
  9.   
  10.     if (diff>1 || diff<-1)  
  11.         return false;  
  12.   
  13.     return IsBalanced(pRoot->m_pLeft)&&IsBalanced(pRoot->m_pRight);  
  14. }  

方法二:由于上述方法在求该结点的的左右子树深度时遍历一遍树,再次判断子树的平衡性时又遍历一遍树结构,造成遍历多次。因此方法二是一边遍历树一边判断每个结点是否具有平衡性。

  1. bool IsBalanced(BinaryTreeNode* pRoot, int* depth)  
  2. {  
  3.     if(pRoot== NULL)  
  4.     {  
  5.         *depth = 0;  
  6.         return true;  
  7.     }  
  8.   
  9.     int nLeftDepth,nRightDepth;  
  10.     bool bLeft= IsBalanced(pRoot->m_pLeft, &nLeftDepth);  
  11.     bool bRight = IsBalanced(pRoot->m_pRight, &nRightDepth);  
  12.       
  13.     if (bLeft && bRight)  
  14.     {  
  15.         int diff = nRightDepth-nLeftDepth;  
  16.         if (diff<=1 || diff>=-1)  
  17.         {  
  18.             *depth = 1+(nLeftDepth > nRightDepth ? nLeftDepth : nRightDepth);  
  19.             return true;  
  20.         }  
  21.     }  
  22.       
  23.     return false;  
  24. }  
  25.   
  26. bool IsBalanced(BinaryTreeNode* pRoot)  
  27. {  
  28.     int depth = 0;  
  29.   
  30.     return IsBalanced(pRoot, &depth);  
  31. }  
 

判断树是否为平衡二叉树

<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]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值