博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

数据结构二叉树的遍历

Posted on 2013-10-06 21:00  皇星客栈--Linux  阅读(370)  评论(0编辑  收藏  举报

数据结构二叉树的遍历,给了个二叉树,前序、中序、后序写出来

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<queue>
  4 #include<stack>
  5 #include<malloc.h>
  6 using namespace std;
  7 
  8 //二叉树结点的描述
  9 typedef struct BiTNode
 10 {
 11     char data;
 12     struct BiTNode *lchild, *rchild;      //左右孩子
 13 }BiTNode,*BiTree;
 14 
 15 //按先序遍历创建二叉树
 16 //BiTree *CreateBiTree()     //返回结点指针类型
 17 //void CreateBiTree(BiTree &root)      //引用类型的参数
 18 void CreateBiTree(BiTNode **root)    //二级指针作为函数参数
 19 {
 20     char ch; //要插入的数据
 21     scanf("\n%c", &ch);
 22     //cin>>ch;
 23     if(ch=='#')
 24         *root = NULL;
 25     else
 26     {
 27         *root = (BiTNode *)malloc(sizeof(BiTNode));
 28         (*root)->data = ch;
 29         printf("请输入%c的左孩子:",ch);
 30         CreateBiTree(&((*root)->lchild));
 31         printf("请输入%c的右孩子:",ch);
 32         CreateBiTree(&((*root)->rchild));
 33     }
 34 }
 35 
 36 //前序遍历的算法程序
 37 void PreOrder(BiTNode *root)
 38 {
 39     if(root==NULL)
 40         return ;
 41     printf("%c ", root->data); //输出数据
 42     PreOrder(root->lchild); //递归调用,前序遍历左子树
 43     PreOrder(root->rchild); //递归调用,前序遍历右子树
 44 }
 45 
 46 //中序遍历的算法程序
 47 void InOrder(BiTNode *root)
 48 {
 49     if(root==NULL)
 50         return ;
 51     InOrder(root->lchild); //递归调用,前序遍历左子树
 52     printf("%c ", root->data); //输出数据
 53     InOrder(root->rchild); //递归调用,前序遍历右子树
 54 }
 55 
 56 //后序遍历的算法程序
 57 void PostOrder(BiTNode *root)
 58 {
 59     if(root==NULL)
 60         return ;
 61     PostOrder(root->lchild);      //递归调用,前序遍历左子树
 62     PostOrder(root->rchild);      //递归调用,前序遍历右子树
 63     printf("%c ", root->data);    //输出数据
 64 }
 65 
 66 /*
 67 二叉树的非递归前序遍历,前序遍历思想:先让根进栈,只要栈不为空,就可以做弹出操作,
 68 每次弹出一个结点,记得把它的左右结点都进栈,记得右子树先进栈,这样可以保证右子树在栈中总处于左子树的下面。
 69 */
 70 void PreOrder_Nonrecursive(BiTree T)     //先序遍历的非递归
 71 {
 72     if(!T)
 73         return ;
 74 
 75     stack<BiTree> s;
 76     s.push(T);
 77 
 78     while(!s.empty())
 79     {
 80         BiTree temp = s.top();
 81         cout<<temp->data<<" ";
 82         s.pop();
 83         if(temp->rchild)
 84             s.push(temp->rchild);
 85         if(temp->lchild)
 86             s.push(temp->lchild);
 87     }
 88 }
 89 
 90 void PreOrder_Nonrecursive1(BiTree T)     //先序遍历的非递归
 91 {
 92     if(!T)
 93         return ;
 94     stack<BiTree> s;
 95     BiTree curr = T;
 96     while(curr != NULL || !s.empty())
 97     {
 98         while(curr != NULL)
 99         {
100             cout<<curr->data<<"  ";
101             s.push(curr);
102             curr = curr->lchild;
103         }
104         if(!s.empty())
105         {
106             curr = s.top();
107             s.pop();
108             curr = curr->rchild;
109         }
110     }
111 }
112 
113 void PreOrder_Nonrecursive2(BiTree T)     //先序遍历的非递归
114 {
115     if(!T)
116         return ;
117 
118     stack<BiTree> s;
119     while(T)          // 左子树上的节点全部压入到栈中
120     {
121         s.push(T);
122         cout<<T->data<<"  ";
123         T = T->lchild;
124     }
125 
126     while(!s.empty())
127     {
128         BiTree temp = s.top()->rchild;  // 栈顶元素的右子树
129         s.pop();                        // 弹出栈顶元素
130         while(temp)          // 栈顶元素存在右子树,则对右子树同样遍历到最下方
131         {
132             cout<<temp->data<<"  ";
133             s.push(temp);
134             temp = temp->lchild;
135         }
136     }
137 }
138 
139 void InOrderTraverse1(BiTree T)   // 中序遍历的非递归
140 {
141     if(!T)
142         return ;
143     BiTree curr = T;    // 指向当前要检查的节点
144     stack<BiTree> s;
145     while(curr != NULL || !s.empty())
146     {
147         while(curr != NULL)
148         {
149             s.push(curr);
150             curr = curr->lchild;
151         }//while
152         if(!s.empty())
153         {
154             curr = s.top();
155             s.pop();
156             cout<<curr->data<<"  ";
157             curr = curr->rchild;
158         }
159     }
160 }
161 
162 void InOrderTraverse(BiTree T)   // 中序遍历的非递归
163 {
164     if(!T)
165         return ;
166     stack<BiTree> s;
167     BiTree curr = T->lchild;    // 指向当前要检查的节点
168     s.push(T);
169     while(curr != NULL || !s.empty())
170     {
171         while(curr != NULL)    // 一直向左走
172         {
173             s.push(curr);
174             curr = curr->lchild;
175         }
176         curr = s.top();
177         s.pop();
178         cout<<curr->data<<"  ";
179         curr = curr->rchild;
180     }
181 }
182 
183 void PostOrder_Nonrecursive1(BiTree T)  // 后序遍历的非递归
184 {
185     stack<BiTree> S;
186     BiTree curr = T ;           // 指向当前要检查的节点
187     BiTree previsited = NULL;    // 指向前一个被访问的节点
188     while(curr != NULL || !S.empty())  // 栈空时结束
189     {
190         while(curr != NULL)            // 一直向左走直到为空
191         {
192             S.push(curr);
193             curr = curr->lchild;
194         }
195         curr = S.top();
196         // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
197         if(curr->rchild == NULL || curr->rchild == previsited)
198         {
199             cout<<curr->data<<"  ";
200             previsited = curr;
201             S.pop();
202             curr = NULL;
203         }
204         else
205             curr = curr->rchild;      // 否则访问右孩子
206     }
207 }
208 
209 void PostOrder_Nonrecursive(BiTree T)  // 后序遍历的非递归     双栈法
210 {
211     stack<BiTree> s1 , s2;
212     BiTree curr ;           // 指向当前要检查的节点
213     s1.push(T);
214     while(!s1.empty())  // 栈空时结束
215     {
216         curr = s1.top();
217         s1.pop();
218         s2.push(curr);
219         if(curr->lchild)
220             s1.push(curr->lchild);
221         if(curr->rchild)
222             s1.push(curr->rchild);
223     }
224     while(!s2.empty())
225     {
226         printf("%c ", s2.top()->data);
227         s2.pop();
228     }
229 }
230 
231 
232 int visit(BiTree T)
233 {
234     if(T)
235     {
236         printf("%c ",T->data);
237         return 1;
238     }
239     else
240         return 0;
241 }
242 
243 void LeverTraverse(BiTree T)   //方法一、非递归层次遍历二叉树
244 {
245     queue <BiTree> Q;
246     BiTree p;
247     p = T;
248     if(visit(p)==1)
249         Q.push(p);
250     while(!Q.empty())
251     {
252         p = Q.front();
253         Q.pop( );
254         if(visit(p->lchild) == 1)
255             Q.push(p->lchild);
256         if(visit(p->rchild) == 1)
257             Q.push(p->rchild);
258     }
259 }
260 void LevelOrder(BiTree BT)     //方法二、非递归层次遍历二叉树
261 {
262     BiTNode *queue[10];//定义队列有十个空间
263     if (BT==NULL)
264         return;
265     int front,rear;
266     front=rear=0;
267     queue[rear++]=BT;
268     while(front!=rear)//如果队尾指针不等于对头指针时
269     {
270         cout<<queue[front]->data<<"  ";  //输出遍历结果
271         if(queue[front]->lchild!=NULL)  //将队首结点的左孩子指针入队列
272         {
273             queue[rear]=queue[front]->lchild;
274             rear++;    //队尾指针后移一位
275         }
276         if(queue[front]->rchild!=NULL)
277         {
278             queue[rear]=queue[front]->rchild;    //将队首结点的右孩子指针入队列
279             rear++;   //队尾指针后移一位
280         }
281         front++;    //对头指针后移一位
282     }
283 }
284 
285 int depth(BiTNode *T)   //树的深度
286 {
287     if(!T)
288         return 0;
289     int d1,d2;
290     d1=depth(T->lchild);
291     d2=depth(T->rchild);
292     return (d1>d2?d1:d2)+1;
293     //return (depth(T->lchild)>depth(T->rchild)?depth(T->lchild):depth(T->rchild))+1;
294 }
295 int CountNode(BiTNode *T)
296 {
297     if(T == NULL)
298         return 0;
299     return 1+CountNode(T->lchild)+CountNode(T->rchild);
300 }
301 
302 int main(void)
303 {
304     BiTNode *root=NULL; //定义一个根结点
305     int flag=1,k;
306     printf("                     本程序实现二叉树的基本操作。\n");
307     printf("可以进行建立二叉树,递归先序、中序、后序遍历,非递归先序、中序遍历及非递归层序遍历等操作。\n");
308 
309     while(flag)
310     {
311         printf("\n");
312         printf("|--------------------------------------------------------------|\n");
313         printf("|                    二叉树的基本操作如下:                     |\n");
314         printf("|                        0.创建二叉树                          |\n");
315         printf("|                        1.递归先序遍历                        |\n");
316         printf("|                        2.递归中序遍历                        |\n");
317         printf("|                        3.递归后序遍历                        |\n");
318         printf("|                        4.非递归先序遍历                      |\n");
319         printf("|                        5.非递归中序遍历                      |\n");
320         printf("|                        6.非递归后序遍历                      |\n");
321         printf("|                        7.非递归层序遍历                      |\n");
322         printf("|                        8.二叉树的深度                        |\n");
323         printf("|                        9.二叉树的结点个数                    |\n");
324         printf("|                        10.退出程序                            |\n");
325         printf("|--------------------------------------------------------------|\n");
326         printf("                        请选择功能:");
327         scanf("%d",&k);
328         switch(k)
329         {
330         case 0:
331             printf("请建立二叉树并输入二叉树的根节点:");
332             CreateBiTree(&root);
333             break;
334         case 1:
335             if(root)
336             {
337                 printf("递归先序遍历二叉树的结果为:");
338                 PreOrder(root);
339                 printf("\n");
340             }
341             else
342                 printf("          二叉树为空!\n");
343             break;
344         case 2:
345             if(root)
346             {
347                 printf("递归中序遍历二叉树的结果为:");
348                 InOrder(root);
349                 printf("\n");
350             }
351             else
352                 printf("          二叉树为空!\n");
353             break;
354         case 3:
355             if(root)
356             {
357                 printf("递归后序遍历二叉树的结果为:");
358                 PostOrder(root);
359                 printf("\n");
360             }
361             else
362                 printf("          二叉树为空!\n");
363             break;
364         case 4:
365             if(root)
366             {
367                 printf("非递归先序遍历二叉树:");
368                 PreOrder_Nonrecursive1(root);
369                 printf("\n");
370             }
371             else
372                 printf("          二叉树为空!\n");
373             break;
374         case 5:
375             if(root)
376             {
377                 printf("非递归中序遍历二叉树:");
378                 InOrderTraverse1(root);
379                 printf("\n");
380             }
381             else
382                 printf("          二叉树为空!\n");
383             break;
384         case 6:
385             if(root)
386             {
387                 printf("非递归后序遍历二叉树:");
388                 PostOrder_Nonrecursive(root);
389                 printf("\n");
390             }
391             else
392                 printf("          二叉树为空!\n");
393             break;
394         case 7:
395             if(root)
396             {
397                 printf("非递归层序遍历二叉树:");
398                 //LeverTraverse(root);
399                 LevelOrder(root);
400                 printf("\n");
401             }
402             else
403                 printf("          二叉树为空!\n");
404             break;
405         case 8:
406             if(root)
407                 printf("这棵二叉树的深度为:%d\n",depth(root));
408             else
409                 printf("          二叉树为空!\n");
410             break;
411         case 9:
412             if(root)
413                 printf("这棵二叉树的结点个数为:%d\n",CountNode(root));
414             else
415                 printf("          二叉树为空!\n");
416             break;
417         default:
418             flag=0;
419             printf("程序运行结束,按任意键退出!\n");
420         }
421     }
422     system("pause");
423     return 0;
424 }