二叉树的先序,中序,后序、层级的递归和非递归遍历和获取叶子节点和树的高度

代码中的二叉树的构造参考了

http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html

代码的思想和图片的来源:好大学慕课浙江大学陈越、何钦铭的《数据结构》

话不多说,直接上代码

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<string.h>
  4 #include <ctype.h>
  5 
  6 //efine binary tree element type
  7 typedef char elementType;
  8 
  9 //define binary tree
 10 typedef struct node{
 11     elementType element;
 12     struct node *left;
 13     struct node *right;
 14     int flag;//为了进行非递归的后序遍历,设置入栈标志位,0表示第一次压栈、弹栈,1表示第二此压栈,弹栈
 15 }bTree,*pBinTree;
 16 
 17 
 18 //define the stack element type
 19 typedef pBinTree dataType;
 20 
 21 
 22 //define a stack to store binary tyoe
 23 typedef struct node2{
 24     dataType element;
 25     struct node2 *next;
 26 }sta,*pStack;
 27 
 28 
 29 /*=======================对树栈的操作==============================*/
 30 pStack createEmptyStack(){
 31     pStack stack = (pStack)malloc(sizeof(sta));
 32     if(stack){
 33         stack->next=NULL;
 34     }
 35 }
 36 
 37 int isStackEmpty(pStack stack){
 38     return(stack->next==NULL);
 39 }
 40 
 41 void push(pStack stack,dataType element){
 42     pStack newNode = (pStack)malloc(sizeof(sta));
 43     newNode->element = element;
 44     newNode->next = stack->next;
 45     stack->next = newNode;
 46 }
 47 
 48 dataType pop(pStack stack){
 49     if(isStackEmpty(stack)){
 50         printf("the stack has been empty\n");
 51         return NULL;
 52     }
 53     pStack temp = stack->next;
 54     stack->next = temp->next;
 55     return temp->element;
 56 }
 57 
 58 int getStackSize(pStack stack){
 59     pStack p = stack->next;
 60     int size=0;
 61     while(p){
 62         size++;
 63         p=p->next;
 64     }
 65     return size;
 66 }
 67 
 68 
 69 
 70 dataType getTop(pStack stack){
 71     if(isStackEmpty(stack)){
 72         printf("the stack has been empty\n");
 73         return NULL;
 74     }
 75     return (stack->next->element);
 76 }
 77 
 78 //定义一个字符型栈
 79 typedef struct node3{
 80     elementType element;
 81     struct node3 *next;
 82 }charSta,*pCharStack;
 83 
 84 /*====================================对字符栈的操作========================================*/
 85 pCharStack createEmptyCharStack(){
 86     pCharStack stack = (pCharStack)malloc(sizeof(charSta));
 87     if(stack){
 88         stack->next=NULL;
 89     }
 90     return stack;
 91 }
 92 
 93 int isCharStackEmpty(pCharStack stack){
 94     return(stack->next==NULL);
 95 }
 96 
 97 void pushCharStack(pCharStack stack,char ch){
 98     pCharStack newNode = (pCharStack)malloc(sizeof(charSta));
 99     newNode->element = ch;
100     newNode->next = stack->next;
101     stack->next=newNode;
102 }
103 
104 
105 elementType popCharStack(pCharStack stack){
106     if(isCharStackEmpty(stack)){
107         return;
108     }
109     pCharStack temp=stack->next;
110     stack->next=temp->next;
111     return temp->element;
112 }
113 
114 /*============================为了对二叉树进行层次遍历,定义一个链式队列存放二叉树=================================*/
115 
116 //定义存放队列元素(二叉树)的链表
117 typedef struct node4{
118     dataType element;
119     struct node4 *next;
120 }lis,*pList;
121 
122 //定义队列的链式存储
123 typedef struct node5{
124     struct node4 *font;//指向队列的头指针
125     struct node4 *rear;//指向队列尾的尾指针
126 }que,*pQueue;
127 
128 pList createEmptyList(){
129     pList list = (pList)malloc(sizeof(lis));
130     if(list){
131         list->next=NULL;
132     }
133     return list;
134 }
135 
136 pQueue createEmptyQueue(){
137     pQueue queue = (pQueue)malloc(sizeof(que));
138     if(queue){
139         queue->font=NULL;
140         queue->rear=NULL;
141     }
142 }
143 
144 int isQueueEmpty(pQueue queue){
145     return (queue->font==NULL);
146 }
147 
148 
149 void addQueue(pQueue queue,dataType element){
150     if(isQueueEmpty(queue)){
151         pList list = createEmptyList();
152         list->element=element;
153         queue->font=list;
154         queue->rear=list;
155     }else{
156         pList list = (pList)malloc(sizeof(lis));
157         list->element=element;
158         list->next = queue->rear->next;
159         queue->rear->next=list;
160         queue->rear=list;
161     }
162 }
163 
164 dataType deleteQueue(pQueue queue){
165     if(isQueueEmpty(queue)){
166         return;
167     }
168     dataType element = queue->font->element;
169     if(queue->font==queue->rear){
170         queue->font=queue->rear=NULL;
171     }else{
172         queue->font = queue->font->next;
173     }
174     return element;
175 }
176 
177 
178 /*==========================二叉树的构造和遍历==================================*/
179 /*
180 构造一棵二叉树,
181 s为存储二叉树的元素的字符数组,s为形如A(B,C(D,E))形式的字符串
182 tree为二叉树创建好的根节点,但是元素为空
183 */
184 pBinTree createBinTree(char *s){
185     int i,isRight;
186     pStack treeStack = createEmptyStack();//存放节点
187     pCharStack charStack = createEmptyCharStack();//存放分隔符
188     pBinTree root = (pBinTree)malloc(sizeof(bTree));
189     pBinTree temp,p;
190     root->element=s[0];
191     root->left=NULL;
192     root->right=NULL;
193     push(treeStack,root);
194     i=1;
195     while(i<strlen(s)){
196         if(s[i]=='('){
197             pushCharStack(charStack,s[i]);
198             isRight=0;
199         }else if(s[i]==','){
200             isRight=1;
201         }else if(s[i]==')'){
202             pop(treeStack);
203             popCharStack(charStack);
204         }else if(isalpha(s[i])){
205             p=(pBinTree)malloc(sizeof(bTree));
206             p->element=s[i];
207             p->left=NULL;
208             p->right=NULL;
209             temp=getTop(treeStack);
210             //printf("%c %c\n",s[i],s[i+1]);
211             if(isRight==1){
212                 temp->right=p;
213             }else{
214                 temp->left=p;
215             }
216 
217             if(s[i+1]=='('){
218                 push(treeStack,p);
219             }
220         }
221         i++;
222     }
223     return root;
224 }
225 
226 //先序遍历
227 void preOrderTraversal(pBinTree tree){
228     if(tree){
229         printf("%c ",tree->element);
230         preOrderTraversal(tree->left);
231         preOrderTraversal(tree->right);
232     }
233 }
234 
235 //先序遍历的非递归方法
236 void preOrderTraversalStack(pBinTree tree){
237     pBinTree t = tree;
238     pStack stack = createEmptyStack();
239     while(t || !isStackEmpty(stack)){
240         while(t){
241             printf("%c ",t->element);
242             push(stack,t);
243             t = t->left;
244         }
245 
246         if(!isStackEmpty(stack)){
247             t = pop(stack);
248             t = t->right;
249         }
250 
251     }
252 
253 }
254 //中序遍历
255 void middlerOrderTraversal(pBinTree tree){
256     if(tree){
257         middlerOrderTraversal(tree->left);
258         printf("%c ",tree->element);
259         middlerOrderTraversal(tree->right);
260     }
261 }
262 
263 //中序遍历的非递归方法
264 void middlerOrderTraversalStack(pBinTree tree){
265     pStack stack = createEmptyStack();
266     pBinTree t =tree;;
267     while(!isStackEmpty(stack) || t){
268         while(t){
269             push(stack,t);
270             t=t->left;
271         }
272         if(!isStackEmpty(stack)){
273             t = pop(stack);
274             printf("%c ",t->element);
275             t = t->right;
276         }
277     }
278 
279 }
280 
281 //后序遍历
282 void postOrderTraversal(pBinTree tree){
283     if(tree){
284         postOrderTraversal(tree->left);
285         postOrderTraversal(tree->right);
286         printf("%c ",tree->element);
287     }
288 }
289 
290 //后序遍历的非递归方法
291 void postOrderTraversalStack(pBinTree tree){
292     pBinTree t = tree;
293     pStack stack = createEmptyStack();
294     while(t || !isStackEmpty(stack)){
295         while(t){
296             t->flag=0;
297             push(stack,t);
298             t=t->left;
299         }
300         if(!isStackEmpty(stack)){
301             t = pop(stack);
302             if(t->flag==0){
303                 t->flag=1;
304                 push(stack,t);
305                 t=t->right;
306             }else{
307                 printf("%c ",t->element);
308                 t=NULL;
309             }
310         }
311     }
312 }
313 
314 /*二叉树的层次遍历*/
315 void levelOrderTraversal(pBinTree tree){
316     pQueue queue = createEmptyQueue();
317     pBinTree tr = tree;
318     if(!tree){
319         return;
320     }
321     addQueue(queue,tr);
322     while(!isQueueEmpty(queue)){
323         tr = deleteQueue(queue);
324         printf("%c ",tr->element);
325         if(tr->left){
326             addQueue(queue,tr->left);
327         }
328         if(tr->right){
329             addQueue(queue,tr->right);
330         }
331     }
332 }
333 
334 /*Application of binary tree teaversal*/
335 
336 //get the mount of leaf node,we just need add condition at preOrderTraversal
337 int getMountOfLeaves(pBinTree tree){
338     pStack stack = createEmptyStack();
339     pBinTree tr =tree;
340     int mount=0;
341     while(tr || !isStackEmpty(stack)){
342         while(tr){
343             if(tr->left==NULL && tr->right==NULL){
344                 mount++;
345             }
346             push(stack,tr);
347             tr=tr->left;
348         }
349         if(!isStackEmpty(stack)){
350             tr = pop(stack);
351             tr=tr->right;
352         }
353     }
354     return mount;
355 }
356 
357 /*get the height of  binary tree, the hight of binary is max(subLeftTree,subRightTree)*/
358 int getHeigthOfBinaryTree(pBinTree tree){
359     int hl,hr,maxH;
360     if(tree){
361         hl=getHeigthOfBinaryTree(tree->left);
362         hr=getHeigthOfBinaryTree(tree->right);
363         maxH=(hl>hr)?hl:hr;
364         return maxH+1;
365     }
366     return 0;
367 }
368 
369 //非递归的方法获取二叉树的高度,其实二叉树的高度就是栈中元素的最大值
370 int getHeigthOfBinaryTreeStack(pBinTree tree){
371     pBinTree t = tree;
372     int hMax=0,stackSize;
373     pStack stack = createEmptyStack();
374     while(t || !isStackEmpty(stack)){
375         while(t){
376             t->flag=0;
377             push(stack,t);
378             t=t->left;
379         }
380         if(!isStackEmpty(stack)){
381             t = pop(stack);
382             if(t->flag==0){
383                 t->flag=1;
384                 push(stack,t);
385                 t=t->right;
386             }else{
387                 /*这里已经弹栈一个元素,因此栈的容量应为 getSize+1*/
388                 stackSize=getStackSize(stack)+1;
389                 //printf("stackSize %d",stackSize);
390                 if(stackSize>hMax){
391                     hMax=stackSize;
392                 }
393                 t=NULL;
394             }
395         }
396     }
397     return hMax;
398 }
399 
400 
401 
402 void main(){
403     char s[]="A(B(D,F(E)),C(G(,H),I))";
404     //char s[]="A(B,C)";
405     pBinTree root =createBinTree(s);
406     printf("preOrderTraversal\n");
407     preOrderTraversal(root);
408     printf("\nPreOrderTraversalStack\n");
409     preOrderTraversalStack(root);
410 
411     printf("\n\n================================\n");
412 
413     printf("\nmiddleOrderTraversal\n");
414     middlerOrderTraversal(root);
415     printf("\nmiddleOrderTraversalStack\n");
416     middlerOrderTraversalStack(root);
417 
418     printf("\n\n================================\n");
419 
420     printf("\npostOrderTraversal\n");
421     postOrderTraversal(root);
422     printf("\npostOrderTraversalStack\n");
423     postOrderTraversalStack(root);
424 
425     printf("\n\n================================\n");
426 
427 
428     printf("\nThe level order traversal\n");
429     levelOrderTraversal(root);
430 
431     printf("\n\n=========the application of binary tree traversal===========\n");
432     int leavesMount = getMountOfLeaves(root);
433     printf("\nnumber one:get the leaves mount:%d\n",leavesMount);
434 
435     int maxHeight = getHeigthOfBinaryTreeStack(root);
436     printf("\nnuber two:get height of the binary tree:%d",maxHeight);
437 
438 }
二叉树的相关操作

 

下面是代码中使用二叉树“A(B(D,F(E)),C(G(,H),I))”的图解,方便大家理解

 

代码的运行结果:

 

 

posted @ 2017-04-08 20:52  浪漫逆风  阅读(589)  评论(0编辑  收藏  举报