[转载]数据结构——二叉树的递归与非递归遍历(先序,中序,后序)

版权声明:欢迎转载 https://blog.csdn.net/l18339702017/article/details/78836862
实验项目五 二叉树基本操作的实现
课程名称:数据结构
实验项目名称:二叉树基本操作的实现

实验目的:

1.掌握树的基本操作—遍历。
实验要求:

1、 分别用递归和非递归的方法实现一棵树的三种遍历。
实验过程:

创建一棵二叉树(二叉树如下图所示);
用递归算法实现对该树的三种遍历;
用非递归算法实现对该树的三种遍历;
输入选项:0或1,0为递归遍历,1为非递归遍历。
根据输入的选项,分别调用递归或非递归算法输出先序、中序、后序遍历序列。
实验报告中给出先序和后序遍历的非递归实现算法代码。

实验结果:

输入:ABD##E##CF#G###(创建二叉树)
输入:0(递归算法)
输出:先序遍历:ABDECFG
中序遍历:DBEAFGC
后序遍历:DEBGFCA
输入:1(非递归实现)
输出:先序遍历:ABDECFG
中序遍历:DBEAFGC
后序遍历:DEBGFCA
代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 #define TElemType char
  4 typedef int Status;
  5 #define OK 1
  6 #define ERROR 0
  7 char ch;
  8 const int MAXSIZE = 110;
  9 
 10 typedef struct BiTNode {
 11     TElemType data;
 12     struct BiTNode *lchild, *rchild;
 13 }BiTNode, *BiTree;
 14 
 15 BiTNode *T;
 16 BiTree q, p;
 17 
 18 typedef BiTree SElemType;
 19 
 20 typedef struct{//定义顺序栈
 21     SElemType *base;
 22     SElemType *top;
 23     int stacksize;
 24 }SqStack;
 25 SqStack S;
 26 
 27 Status InitStack(SqStack &S){
 28     S.base = new SElemType[MAXSIZE];
 29     if(!S.base) exit(OVERFLOW);
 30     S.top = S.base;
 31     S.stacksize = MAXSIZE;
 32     return OK;
 33 }
 34 Status Push(SqStack &S, SElemType e)//入栈
 35 {
 36     if(S.top - S.base == S.stacksize)  //判断栈满
 37         return ERROR;
 38     *S.top++ = e;                     //元素e压入栈顶,栈顶指针上移一位;
 39     return OK;
 40  }
 41 Status Pop(SqStack &S, SElemType &e){//出栈
 42     if(S.top == S.base)   return ERROR;
 43     e = *--S.top;
 44     return OK;
 45 }
 46 SElemType GetTop(SqStack S){//取栈顶元素
 47     if(S.top != S.base)   return *(S.top - 1);
 48 }
 49 Status StackEmpty(SqStack &S){
 50     if(S.top - S.base == 0)    return OK;
 51     else return ERROR;
 52 }
 53 
 54 void CreatBiTree(BiTree &T){//建树
 55     cin >> ch;//读入字符
 56     if(ch == '#') T = NULL;//如果字符为'#',说明已经到了叶结点
 57     else{//递归
 58         T = new BiTNode;
 59         T->data = ch;
 60         CreatBiTree(T->lchild);
 61         CreatBiTree(T->rchild);
 62     }
 63 }
 64 void DgXx(BiTree T){//递归先序
 65     if(T){
 66         cout << T->data;
 67         DgXx(T->lchild);
 68         DgXx(T->rchild);
 69     }
 70 }
 71 void DgZx(BiTree T){//递归中序
 72     if(T){
 73         DgZx(T->lchild);
 74         cout << T->data;
 75         DgZx(T->rchild);
 76     }
 77 }
 78 void DgHx(BiTree T){//递归后序
 79     if(T){
 80         DgHx(T->lchild);
 81         DgHx(T->rchild);
 82         cout << T->data;
 83     }
 84 }
 85 void InRrderTraverse0(BiTree T){//非递归先序
 86     InitStack(S);//初始化栈S
 87     p = T;
 88     while(p || !StackEmpty(S)) {//如果树不为空或者栈不为空
 89         if(p){
 90             Push(S, p) ;//将结点入栈
 91             cout << p->data;//输出根结点的值
 92             p = p->lchild ;//把左孩子作为根节点
 93         }
 94         else{//如果树空,说明左树已经遍历完成
 95             Pop(S, p) ;//弹出结点
 96             p = p->rchild ;//开始遍历右树
 97         }
 98     }
 99 }
100 void InRrderTraverse1(BiTree T){//非递归中序遍历
101     InitStack(S);//初始化栈
102     p = T;
103     q = new BiTNode;
104     while(p || !StackEmpty(S)){
105         if(p){//p非空
106             Push(S, p);//根指针进栈
107             p = p->lchild;//根指针进栈,遍历左子树
108         }
109         else{//p为空
110             Pop(S, q);//退栈
111             cout << q->data;//访问根结点
112             p = q->rchild;//遍历右子树
113         }
114     }
115 }
116 void InRrderTraverse2(BiTree T){//非递归后序遍历
117     InitStack(S);
118     Push(S, T);//把根节点进栈
119     BiTNode *pre, *cur;
120     cur = NULL;//当前结点
121     pre = NULL;//上一结点
122     while(!StackEmpty(S)){//栈非空
123         cur = GetTop(S);//把根节点给当前结点
124         if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
125         {//如果左右子树都没有或者左右子树都已经访问过了
126             cout << cur->data;//直接输出根结点
127             Pop(S, cur);//将此时的根节点弹出
128             pre = cur;//更新pre
129         }
130         else{//记得先进右子树后进左子树,这样输出的顺序才对。
131             if(cur->rchild != NULL){//如果右子树不为空
132                 Push(S, cur->rchild) ;//把右子树进栈
133             }
134             if(cur->lchild != NULL){//如果左子树不为空
135                 Push(S, cur->lchild) ;//把左子树进栈
136             }
137         }
138     }
139 }
140 int main(){
141     CreatBiTree(T);
142     int temp;
143     printf("请输入遍历二叉树的方法,0:递归遍历,1:递归遍历,其他数字:结束询问\n");
144     while(scanf("%d",&temp) != EOF){
145         if(temp == 0){
146             cout << "先序遍历:\n";
147             DgXx(T);
148             cout << endl;
149             cout << "中序遍历:\n";
150             DgZx(T);
151             cout << endl;
152             cout << "后序遍历:\n";
153             DgHx(T);
154             cout << endl;
155         }
156         else if(temp == 1){
157             cout << "先序遍历:\n";
158             InRrderTraverse0(T);
159             cout << endl;
160             cout << "中序遍历:\n";
161             InRrderTraverse1(T);
162             cout << endl;
163             cout << "后序遍历:\n";
164             InRrderTraverse2(T);
165             cout << endl;
166         }
167         else    break;
168         printf("请输入遍历二叉树的方法,0:递归遍历,1:递归遍历,其他数字:结束询问\n");
169     }
170         printf("感谢使用\n");
171     return 0;
172 }

 


---------------------
作者:hpu-辞树
来源:CSDN
原文:https://blog.csdn.net/l18339702017/article/details/78836862
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2018-11-22 18:05  jjlovezz  阅读(129)  评论(0)    收藏  举报