【剑指offer】判断二叉树是否为平衡二叉树

2013-09-03 14:16:51

面试题39:求二叉树的深度、判断二叉树是否为平衡二叉树

小结:

  1. 根据平衡二叉树的定义,需要判断每个结点,因此,需要遍历二叉树的所有结点,并判断以当前结点为根的树是否为二叉树;
  2. 用后序遍历的方式,先判断左右子树是否为平衡的,在判断当前节点;
  3. 可以对每个结点求深度,根据深度判断,如函数IsBanlancedTreeBasic所示,但这种方法存在重复遍历,效率较低;
  4. 后序遍历时,一边判断是否为平衡二叉树,一边求而二叉树的深度,这样就避免了重复遍历,如函数IsBanlancedTree所示。

代码编写注意事项:

  1. 注意IsBanlancedTreeSub中需同时带回深度,因此在返回为true时,需要更新*pDepth的值;
  2. 写代码时,注意下面的代码由于优先级会造成错误

if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1)

因此改为:

1 int diff = lchilDepth - rchilDepth;
2     if ( diff < -1 || diff > 1)
3     {
4         return false;
5     }

 


 

代码(测试通过,暂未发现问题,欢迎交流指正):

  1 #include <iostream>
  2 #include <cassert>
  3 using namespace std;
  4 
  5 typedef char DataType;
  6 const DataType LeafNode = '*';
  7 const size_t SIZE = 1000;
  8 
  9 typedef struct binaryTreeNode
 10 {
 11     DataType data;
 12     binaryTreeNode *lchild;
 13     binaryTreeNode *rchild;
 14 }BTNode,*PBTNode;
 15 
 16 //创建二叉树
 17 PBTNode CreatBiTree(PBTNode &pRoot)
 18 {
 19     DataType newData = 0;
 20 
 21     cin>>newData;
 22 
 23     if (newData == LeafNode)
 24     {
 25         return NULL;
 26     }
 27 
 28     pRoot = new BTNode;
 29     pRoot->data = newData;
 30 
 31     pRoot->lchild = CreatBiTree(pRoot->lchild);
 32     pRoot->rchild = CreatBiTree(pRoot->rchild);
 33 
 34     return pRoot;
 35 }
 36 
 37 //访问二叉树结点
 38 void VisitBiTreeNode(const PBTNode &pBTNode)
 39 {
 40     assert(NULL != pBTNode);
 41     cout<<pBTNode->data<<"\t";
 42 }
 43 
 44 //前序遍历二叉树
 45 void PreOrder(const PBTNode &pRoot)
 46 {
 47     if (pRoot != NULL)
 48     {
 49         VisitBiTreeNode(pRoot);
 50         PreOrder(pRoot->lchild);
 51         PreOrder(pRoot->rchild);
 52     }
 53 }
 54 
 55 //中序遍历二叉树
 56 void InOrder(const PBTNode &pRoot)
 57 {
 58     if (pRoot != NULL)
 59     {
 60         InOrder(pRoot->lchild);
 61         VisitBiTreeNode(pRoot);
 62         InOrder(pRoot->rchild);
 63     }
 64 }
 65 
 66 //后序遍历二叉树
 67 void PostOrder(const PBTNode &pRoot)
 68 {
 69     if (pRoot != NULL)
 70     {
 71         PostOrder(pRoot->lchild);
 72         PostOrder(pRoot->rchild);
 73         VisitBiTreeNode(pRoot);
 74     }
 75 }
 76 
 77 //求二叉树深度
 78 size_t GetDepthOfBiTree(const PBTNode &pRoot)
 79 {
 80     if (NULL == pRoot)
 81     {
 82         return 0;
 83     }
 84 
 85     size_t lchilDepth = GetDepthOfBiTree(pRoot->lchild);
 86     size_t rchilDepth = GetDepthOfBiTree(pRoot->rchild);
 87 
 88     return ( (lchilDepth > rchilDepth) ? (lchilDepth + 1) : (rchilDepth + 1) );
 89 }
 90 
 91 
 92 //判断是否平衡二叉树,求每个结点的深度,有重复遍历
 93 bool IsBanlancedTreeBasic(const PBTNode &pRoot)
 94 {
 95     if (pRoot == NULL)   //若左子树为空,右子树的深度超过1,判断会出错
 96         return true;
 97 
 98     //return ( IsBanlancedTree(pRoot->lchild) && IsBanlancedTree(pRoot->rchild) );
 99 
100     if ( !IsBanlancedTreeBasic(pRoot->lchild) || !IsBanlancedTreeBasic(pRoot->rchild) )
101     {
102         return false;
103     }
104 
105     size_t lchilDepth = GetDepthOfBiTree(pRoot->lchild);
106     size_t rchilDepth = GetDepthOfBiTree(pRoot->rchild);
107     int diff = lchilDepth - rchilDepth;
108     //if ( (lchilDepth - rchilDepth) < -1 || (lchilDepth - rchilDepth) > 1)
109     if ( diff < -1 || diff > 1)
110     {
111         return false;
112     }
113 
114     return true;
115 }
116 
117 //判断是否平衡二叉树,优化,没有重复遍历
118 bool IsBanlancedTreeSub(const PBTNode &pRoot,size_t *pDepth)
119 {
120     if (pRoot == NULL)  
121     {
122         *pDepth = 0;
123         return true;
124     }
125 
126     size_t lchildDepth = 0;
127     size_t rchildDepth = 0;
128 
129     if ( !IsBanlancedTreeSub(pRoot->lchild,&lchildDepth) || !IsBanlancedTreeSub(pRoot->rchild,&rchildDepth) )
130     {
131         return false;
132     }
133 
134     int diff = lchildDepth - rchildDepth;
135 
136     if ( diff < -1 || diff > 1)
137     {
138         return false;
139     }
140 
141     *pDepth = lchildDepth > rchildDepth ? (lchildDepth + 1) : (rchildDepth + 1);
142     return true;
143 }
144 
145 bool IsBanlancedTree(const PBTNode &pRoot)
146 {
147     size_t Depth = 0;
148     return IsBanlancedTreeSub(pRoot,&Depth);
149 }
150 
151 
152 void DestoryBiTreeNode(PBTNode pRoot)
153 {
154     delete pRoot;
155 }
156 
157 //销毁二叉树
158 void DestoryBiTree(PBTNode &pRoot)
159 {
160     if (pRoot != NULL)
161     {
162         DestoryBiTree(pRoot->lchild);
163         DestoryBiTree(pRoot->rchild);
164         DestoryBiTreeNode(pRoot);
165     }
166 }
167 
168 //测试二叉树相关操作
169 void TestBinaryTree()
170 {
171     PBTNode pRoot = NULL;
172 
173     cout<<"Test IsBanlancedTree..."<<endl;
174 
175     //测试IsBanlancedTree
176     while (1)
177     {
178         cout<<"Please enter the binary tree,'*' for leaf node"<<endl;
179         CreatBiTree(pRoot);
180 
181         //Test PreOrder...
182         //cout<<"Test PreOrder..."<<endl;
183         cout<<"The pre order is :"<<endl;
184         PreOrder(pRoot);
185         cout<<endl;
186 
187         //Test InOrder...
188         //cout<<"Test InOrder..."<<endl;
189         cout<<"The in order is :"<<endl;
190         InOrder(pRoot);
191         cout<<endl;
192 
193         //Test PostOrder...
194         //cout<<"Test PostOrder..."<<endl;
195         cout<<"The post order is :"<<endl;
196         PostOrder(pRoot);
197         cout<<endl;
198 
199         cout<<"IsBanlancedTree : "<<IsBanlancedTree(pRoot)<<endl;
200         cout<<"IsBanlancedTreeBasic : "<<IsBanlancedTreeBasic(pRoot)<<endl;
201 
202         cout<<"Test DestoryBiTree..."<<endl;
203         DestoryBiTree(pRoot);
204     }
205 
206     /*cout<<"Test DestoryBiTree..."<<endl;
207     DestoryBiTree(pRoot);*/
208 }
209 
210 int main()
211 {
212     TestBinaryTree();
213     return 0;
214 }

测试结果:

Test IsBanlancedTree...
Please enter the binary tree,'*' for leaf node
ab**c**
The pre order is :
a       b       c
The in order is :
b       a       c
The post order is :
b       c       a
IsBanlancedTree : 1
IsBanlancedTreeBasic : 1
Test DestoryBiTree...
Please enter the binary tree,'*' for leaf node
ab***
The pre order is :
a       b
The in order is :
b       a
The post order is :
b       a
IsBanlancedTree : 1
IsBanlancedTreeBasic : 1
Test DestoryBiTree...
Please enter the binary tree,'*' for leaf node
a**
The pre order is :
a
The in order is :
a
The post order is :
a
IsBanlancedTree : 1
IsBanlancedTreeBasic : 1
Test DestoryBiTree...
Please enter the binary tree,'*' for leaf node
abc****
The pre order is :
a       b       c
The in order is :
c       b       a
The post order is :
c       b       a
IsBanlancedTree : 0
IsBanlancedTreeBasic : 0
Test DestoryBiTree...
Please enter the binary tree,'*' for leaf node
abcd****e*f**
The pre order is :
a       b       c       d       e       f
The in order is :
d       c       b       a       e       f
The post order is :
d       c       b       f       e       a
IsBanlancedTree : 0
IsBanlancedTreeBasic : 0
Test DestoryBiTree...
Please enter the binary tree,'*' for leaf node
abd**e**cf***
The pre order is :
a       b       d       e       c       f
The in order is :
d       b       e       a       f       c
The post order is :
d       e       b       f       c       a
IsBanlancedTree : 1
IsBanlancedTreeBasic : 1
Test DestoryBiTree...
Please enter the binary tree,'*' for leaf node
**
The pre order is :
        请按任意键继续. . .

 

posted @ 2013-09-03 14:49  永不止步,永无止境  阅读(823)  评论(0编辑  收藏  举报