二叉树的各种操作

二叉树的操作实现

这里的二叉树全部都是用二叉链实现,算法都是一些简单的递归

  • 根据二叉树括号表示法字符串str生成对应的二叉树链式存储结构
  • 输出二叉树
  • 先序遍历、中序遍历、后序遍历
  • 销毁二叉树
  • 查找值为x的结点
  • 求二叉树的高度
  • 求二叉树元素的最大值
  • 求二叉树结点个数
  • 输出所有的叶子结点
  • 求二叉树中结点值x的层数
  • 求二叉树第k层的结点个数
  • 求第k层上叶子结点的个数
  • 求二叉树中所有单分支结点个数
  • 判断两棵树是否相似
  • 输出值为x的结点的所有祖先
  • 输出值为x的结点的所有子孙结点
  • 判断值为x的结点和值为y的结点是否为兄弟
  • 将二叉树b1复制到二叉树b2
  • 将二叉树的所有左右子树进行交换
  • 判断一颗二叉树是否是完全二叉树
  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 
  4 typedef char ElemType;
  5 typedef struct node 
  6 {
  7     ElemType data;
  8     struct node *lchild;
  9     struct node *rchild;
 10 }BTNode;
 11 
 12 const int MaxSize = 100 + 10;    
 13 
 14 //根据二叉树括号表示法字符串str生成对应的二叉树链式存储结构
 15 void CreateBTree(BTNode * &b, char *str)
 16 {
 17     BTNode *St[MaxSize], *p;        //St作为顺序栈
 18     int top = -1, k,j = 0;            //top作为栈顶指针
 19     char ch;
 20     b = NULL;
 21     ch = str[j];
 22     while (ch != '\0')
 23     {
 24         switch (ch)
 25         {
 26         case '(':top++; St[top] = p; k = 1; break;        //开始处理左孩子结点
 27         case ')':top--; break;                            //栈顶结点的子树处理完毕
 28         case ',':k = 2; break;                            //开始处理右孩子结点
 29         default:
 30             p = (BTNode *)malloc(sizeof(BTNode));        //创建一个结点,由p指向它
 31             p->data = ch;
 32             p->lchild = p->rchild = NULL;                
 33             if (b == NULL)  b = p;                        //若尚未创建根节点
 34             else
 35             {
 36                 switch (k)
 37                 {
 38                 case 1:St[top]->lchild = p; break;
 39                 case 2:St[top]->rchild = p; break;
 40                 }
 41             }
 42         }
 43         j++;                                            //继续扫描str
 44         ch = str[j];
 45     }
 46 }
 47 
 48 //输出二叉树DispBTree(b)
 49 void DispBTree(BTNode *b)
 50 {
 51     if (b != NULL)
 52     {
 53         printf("%c", b->data);
 54         if (b->lchild != NULL || b->rchild != NULL)
 55         {
 56             printf("(");                            //有孩子结点时才输出“(”
 57             DispBTree(b->lchild);                    //递归处理左子树
 58             if (b->rchild != NULL)  printf(",");    //有右孩子结点时才输出“,”
 59             DispBTree(b->rchild);                    //递归处理右子树
 60             printf(")");                            //有孩子结点时才输出
 61         }
 62     }
 63 }
 64 
 65 //先序遍历
 66 void PreOrder(BTNode * b)
 67 {
 68     if (b != NULL)
 69     {
 70         printf("%c", b->data);
 71         PreOrder(b->lchild);
 72         PreOrder(b->rchild);
 73     }
 74 }
 75 //中序遍历
 76 void InOrder(BTNode * b)
 77 {
 78     if (b != NULL)
 79     {
 80         InOrder(b->lchild);
 81         printf("%c", b->data);
 82         InOrder(b->rchild);
 83     }
 84 }
 85 //后序遍历
 86 void PostOrder(BTNode * b)
 87 {
 88     if (b != NULL)
 89     {
 90         InOrder(b->lchild);
 91         InOrder(b->rchild);
 92         printf("%c", b->data);
 93     }
 94 }
 95 
 96 //销毁二叉树
 97 void DestroyBTree(BTNode *& b)
 98 {
 99     if (b != NULL)
100     {
101         DestroyBTree(b->lchild);
102         DestroyBTree(b->rchild);
103         free(b);
104     }
105 }
106 
107 
108 //查找值为x的结点
109 BTNode *FindNode(BTNode *b, ElemType x)
110 {
111     BTNode *p;
112     if (b == NULL)  return NULL;
113     else if (b->data == x)  return b;
114     else
115     {
116         p = FindNode(b->lchild, x);
117         if (p != NULL)  return p;
118         else  return FindNode(b->rchild, x);
119     }
120 }
121 
122 //求二叉树的高度
123 int BTHeight(BTNode *b)
124 {
125     int lchildh, rchildh;
126     if (b == NULL)  return 0;
127     else
128     {
129         lchildh = BTHeight(b->lchild);
130         rchildh = BTHeight(b->rchild);
131         return lchildh > rchildh ? (lchildh + 1) : (rchildh + 1);
132     }
133 }
134 
135 //求二叉树元素的最大值
136 int BTMax(BTNode *b)
137 {
138     if (b == NULL)  return 0;
139     else
140     {
141         int m1 = BTMax(b->lchild);
142         int m2 = BTMax(b->rchild);
143         int m3 = b->data;
144         if (m1 > m2)  return m1 > m3 ? m1 : m3;
145         else  return m2 > m3 ? m2 : m3;
146     }
147 }
148 
149 //求二叉树结点个数
150 int BTNum(BTNode * b)
151 {
152     if (b == NULL)  return 0;
153     else  return BTNum(b->lchild) + BTNum(b->rchild) + 1;
154 }
155 
156 //输出所有的叶子结点
157 void DispLeaf(BTNode *b)
158 {
159     if (b != NULL)
160     {
161         if (b->lchild == NULL && b->rchild == NULL)
162             printf("%c", b->data);
163         DispLeaf(b->lchild);
164         DispLeaf(b->rchild);
165     }
166 }
167 
168 //求二叉树中结点值x的层数
169 //返回0表示未找到,h初始置为0
170 int BTLevel(BTNode *b, ElemType x, int h)
171 {
172     int level;
173     if (b == NULL)  return 0;
174     else if (b->data == x)  return h;
175     else
176     {
177         level = BTLevel(b->lchild, x, h + 1);
178         if (level != 0)  return level;
179         else  return BTLevel(b->rchild, x, h + 1);
180     }
181 }
182 
183 //求二叉树第k层的结点个数
184 //当前层数h初始置为0
185 int BTKlevel(BTNode *b,int h, int k)
186 {
187     if (b == NULL)  return 0;
188     else
189     {
190         if (h == k)  return 1;
191         if (h < k)   return (BTKlevel(b->lchild, h + 1, k) + BTKlevel(b->rchild,h + 1,k));
192     }
193 }
194 
195 //求第k层上叶子结点的个数
196 int BTKlevelLeaf(BTNode *b, int h, int k)
197 {
198     if (b == NULL)  return 0;
199     else
200     {
201         if (h == k && b->lchild == NULL && b->rchild == NULL)  return 1;
202         if (h < k)   return (BTKlevelLeaf(b->lchild, h + 1, k) + BTKlevelLeaf(b->rchild, h + 1, k));
203     }
204     return 0;                //其它情况返回0
205 }
206 
207 //求二叉树中所有单分支结点个数
208 int BTSingleSonNode(BTNode * b)
209 {
210     if (b == NULL)  return 0;
211     else if ((b->lchild == NULL && b->rchild != NULL) || (b->lchild != NULL && b->rchild == NULL))  return BTSingleSonNode(b->lchild) + BTSingleSonNode(b->rchild) + 1;
212     else  return BTSingleSonNode(b->lchild) + BTSingleSonNode(b->rchild);
213 }
214 
215 //判断两棵树是否相似
216 //形态一样,结点值可以不同
217 bool BTLike(BTNode *b1, BTNode *b2)
218 {
219     bool flag1, flag2;
220     if (b1 == NULL && b2 == NULL)  return true;
221     else if (b1 == NULL || b2 == NULL)  return false;
222     else
223     {
224         flag1 = BTLike(b1->lchild, b2->lchild);
225         flag2 = BTLike(b1->rchild, b2->rchild);
226         return flag1 && flag2;
227     }
228 }
229 
230 //输出值为x的结点的所有祖先
231 //f(b,x)=true表示以结点b为根节点的二叉树包含x
232 bool BTAncestor(BTNode *b, ElemType x)
233 {
234     if (b == NULL)  return false;
235     else if ((b->lchild != NULL && b->lchild->data == x) || (b->rchild != NULL && b->rchild->data == x))
236     {
237         printf("%c", b->data);
238         return true;
239     }
240     else
241     {
242         int flag1 = BTAncestor(b->lchild, x);
243         int flag2 = BTAncestor(b->rchild, x);        //考虑到可能存在多个x,分开写
244         if(flag1 || flag2)  printf("%c", b->data);
245         return true;
246     }
247     return false;
248 }
249 
250 //输出值为x的结点的所有子孙结点
251 void BTChild(BTNode *b, ElemType x)
252 {
253     if (b != NULL)
254     {
255         if (b->data == x)
256         {
257             PreOrder(b->lchild);
258             PreOrder(b->rchild);
259         }
260         else
261         {
262             BTChild(b->lchild,x);
263             BTChild(b->rchild,x);
264         }
265     }
266 }
267 
268 //判断值为x的结点和值为y的结点是否为兄弟
269 bool BTBrother(BTNode *b, ElemType x, ElemType y)
270 {
271     if (b == NULL)  return false;
272     else
273     {
274         if (b->lchild != NULL && b->rchild != NULL)
275             if ((b->lchild->data == x && b->rchild->data == y) || (b->lchild->data == y && b->rchild->data == x))
276                 return true;
277         return BTBrother(b->lchild, x, y) || BTBrother(b->rchild, x, y);
278     }
279 }
280 
281 //将二叉树b1复制到二叉树b2
282 void BTCopy(BTNode *b1, BTNode * &b2)
283 {
284     if (b1 == NULL)      b2 = NULL;
285     else
286     {
287         b2 = (BTNode *)malloc(sizeof(BTNode));
288         b2->data = b1->data;
289         BTCopy(b1->lchild, b2->lchild);
290         BTCopy(b1->rchild, b2->rchild);
291     }
292 }
293 
294 //将二叉树的所有左右子树进行交换
295 void BTSwap(BTNode *b1, BTNode * &b2)
296 {
297     if (b1 == NULL)  b2 = NULL;
298     else
299     {
300         b2 = (BTNode *)malloc(sizeof(BTNode));
301         b2->data = b1->data;
302         BTSwap(b1->rchild, b2->lchild);
303         BTSwap(b1->lchild, b2->rchild);
304     }
305 }
306 
307 
308 //判断一颗二叉树是否是完全二叉树
309 //两条规则,违反任意一条均不是完全二叉树
310 //1、某结点无左孩子,则一定没有右孩子
311 //2、若某结点缺少左孩子或右孩子,则其所有后继(层次遍历的后继)一定无孩子
312 bool BTComp(BTNode *b)
313 {
314     BTNode *Qu[MaxSize], *p;            //定义一个队列用于层次遍历
315     int front = 0, rear = 0;            //环形队列的队头和队尾指针
316     bool cm = true;                        //cm为真表示二叉树为完全二叉树
317     bool flag = true;                    //flag为真表示所有结点到目前为止都有左右孩子
318     if (b == NULL)  return true;
319     rear++;
320     Qu[rear] = b;                        //根结点入队
321     while (front != rear)                //队列不为空
322     {
323         front = (front + 1) % MaxSize;
324         p = Qu[front];                    //队首出队
325         if (p->lchild == NULL)  
326         {
327             flag = false;
328             if (p->rchild != NULL)        //没有左孩子,则一定没有右孩子
329             {
330                 cm = false;
331                 break;
332             }
333         }
334         else
335         {
336             if ((!flag))                //出现空缺少左孩子或右孩子之后,所有的结点均无孩子
337             {
338                 cm = false;
339                 break;
340             }
341             rear = (rear + 1) % MaxSize;
342             Qu[rear] = p->lchild;            //左孩子入队
343             if (p->rchild == NULL)  flag = false;
344             else
345             {
346                 rear = (rear + 1) % MaxSize;
347                 Qu[rear] = p->rchild;        //右孩子入队
348             }
349         }
350     }
351     return cm;
352 }
353 
354 int main()
355 {
356     BTNode *b1, *b2;
357     char str1[] = "A(B(D(,G)),C(E(,G),F))";
358     char str2[] = "A(B(D,D),C(E))";
359     CreateBTree(b2,str2);
360     printf("%d\n", BTComp(b2));
361     return 0;
362 }

 

 

参考资料:《数据结构教程》李春葆等

上一篇:西南科技大学OJ题 利用二叉树中序及先序遍历确定该二叉树的后序序列0984


下一篇:用迭代法求x=sqrt{a}。求平方根的迭代公式为