所谓的平衡二叉树,就是指数中任一结点的左右子树深度相差不超过1。下图就是一个平衡二叉树:
解法1:很容易想到,遍历每一个结点时,调用函数TreeDepth()求得左右子树的深度,如果所有左右子树的深度相差不超过1,那么该树就是一个平衡二叉树。代码如下:
1 bool isBalan(TreeNode *root) 2 { 3 if(!root) 4 return true; 5 int left = TreeDepth(root->left); 6 int right = TreeDepth(root->right); 7 int diff = left-right; 8 if(diff<-1 && diff>1) 9 return false; 10 11 return isBalan(root->left)&&isBalan(root->right); 12 }
上述虽然代码简单,但是效率却十分低下,因为同一个节点被访问了多次。
解法2: 采用后序遍历的方式遍历每一个结点,在遍历到一个结点之前已经遍历了它的左右子树,只要在遍历每个结点的时候记录它的深度,那么就可以一边遍历一边判断每个结点是否是平衡的。主要代码:
1 bool isBalan(TreeNode *root,int *depth) 2 { 3 if(root==NULL) 4 { 5 // depth的值其实就是对应的left、right的深度 6 *depth=0; 7 return true; 8 } 9 int left,right; 10 11 // 用的是C里面的地址传参 12 if(isBalan(root->left,&left) && isBalan(root->right,&right)) 13 { 14 int diff = left-right; 15 if(diff>=-1 && diff<=1) 16 { 17 *depth=1+((left>right)?left:right); 18 return true; 19 } 20 } 21 return false; 22 }
我们用后序遍历的方式遍历整棵二叉树。在遍历某结点的左右子结点之后,我们可以根据它的左右子结点的深度判断它是不是平衡的,并得到当前结点的深度。当最后遍历到树的根结点的时候,也就判断了整棵二叉树是不是平衡二叉树了。
求二叉树深度的代码如下:
1 int TreeDepth(BinaryTreeNode *pRoot) 2 { 3 if(pRoot==NULL) 4 return 0; 5 int left = TreeDepth(pRoot->left); 6 int right = TreeDepth(pRoot->right); 7 return (left>right)?(left+1):(right+1); 8 }