二叉树的建立和遍历

 

 

 


  1 #include<iostream>
  2 #include <stack>
  3 
  4 using namespace std;
  5 
  6 //本文用前序遍历、中序遍历、后序遍历实现二叉树的建立,再用三种遍历方法实现遍历输出
  7 
  8 //构建节点的数据结构
  9 typedef struct BiNode
 10 {
 11     char data;
 12     struct BiNode *lchild,*rchild;
 13 }BiNode,*BiTree;
 14 
 15 /*
 16 //构建节点的数据结构
 17 typedef struct BiNode
 18 {
 19     char data;
 20     struct BiNode lchild,rchild; //这里写成这样子是不对的,因为还没有定义完成BiNode结构体,并不知道给lchild分配多少空间,所以会报错,
 21                                     但是如果像上面一样定义指针的话,不需要分配空间,所以不会报错
 22 }BiNode,*BiTree;
 23 */
 24 
 25 //前序遍历方式创建二叉树
 26 //void createPreBst(BiTree T) 这里这样子写会出现错误,因为值传递和地址传递和引用传递的区别。
 27 
 28 void createPreBst(BiTree &T) //指针的值改变,之后就会被释放,应该改变指针的地址。 这里可以是引用也可以是指针
 29 {
 30     char inPut;
 31     scanf("%c",&inPut);
 32     if(inPut == '#')
 33     {
 34         T = NULL;
 35     }
 36     else
 37     {
 38         T = (BiTree)malloc(sizeof(BiNode));
 39         if(T == NULL)
 40         exit(OVERFLOW);
 41 
 42         T->data = inPut;
 43         createPreBst(T->lchild);
 44         createPreBst(T->rchild);
 45     }
 46 }
 47 
 48 /* 这里面是不对的,不能仅仅用简单的交换来达到中序和后序的实现!!
 49 //中序遍历方式创建二叉树
 50 void createInBst(BiTree &T)
 51 {
 52     char inPut;
 53     scanf("%c",&inPut);
 54     if(inPut == '#')
 55     {
 56         T = NULL;
 57     }
 58     else
 59     {
 60         T = (BiTree)malloc(sizeof(BiNode));
 61         if(T == NULL)
 62             exit(OVERFLOW);
 63 
 64         
 65 
 66         createInBst(T->lchild);
 67         T->data = inPut;
 68         createInBst(T->rchild);
 69     }
 70 }
 71 
 72 
 73 
 74 void createPostBst(BiTree &T)
 75 {
 76     char inPut;
 77     scanf("%c",&inPut);
 78      if(inPut == '#')
 79     {
 80         T = NULL;
 81     }
 82     
 83     if(T==NULL)
 84           T = (BiTree)malloc(sizeof(BiNode));
 85         //if(T == NULL)
 86         //    exit(OVERFLOW);
 87 
 88         
 89         createPostBst(T->lchild);
 90         createPostBst(T->rchild);
 91         T->data = inPut;
 92     
 93 }
 94 */
 95 
 96 
 97 //前序遍历方式输出(递归法)
 98 
 99 void preOrder(BiTree T)
100 {
101     if(T == NULL)
102     {
103         return;
104     }
105     printf("%c ", T->data);
106     preOrder(T->lchild);
107     preOrder(T->rchild);
108 }
109 
110 //前序遍历方式输出(非递归法) 用一个栈来实现
111 void preOrder01(BiTree T)
112 {
113     stack <BiTree> sta;
114     if( T == NULL)
115     {
116         return;
117     }
118     //while(T || sta.empty() != 0) 这里的empty的值不能是零,empty() 堆栈为空则返回真
119     while(T || sta.empty() != true)
120     {
121         while(T)
122         {
123             sta.push(T);
124             printf("%c",T->data);
125             T = T->lchild;
126         }
127 
128         T = sta.top();
129         sta.pop();
130         T = T->rchild;
131     }
132 
133 }
134 
135 //中序遍历方式输出(递归法)
136 void inOrder(BiTree T)
137 {
138     if(T == NULL)
139     {
140         return;
141     }
142     
143     inOrder(T->lchild);
144     printf("%c ", T->data);
145     inOrder(T->rchild);
146 }
147 
148 //中序遍历方式输出(非递归法)  
149 void inOrder02(BiTree T)
150 {
151     if(T == NULL)
152     {
153         return;
154     }
155     stack<BiTree > sta;
156 
157     //while(T || sta.empty() != 0) 这里的empty的值不能是零,empty() 堆栈为空则返回真
158     while(T || sta.empty() != true)
159     {
160         while(T)
161         {
162             sta.push(T);
163             T = T->lchild;
164         }
165 
166         T = sta.top();
167         printf("%c" , T->data);
168         sta.pop();
169         T = T->rchild ;
170     }
171 
172 }
173 
174 //后序遍历方式输出(递归法)
175 void postOrder(BiTree &T)
176 {
177     if(T == NULL)
178     {
179         return;
180     }
181     
182     postOrder(T->lchild);
183     postOrder(T->rchild);
184     printf("%c ", T->data);
185 }
186 
187 //后序遍历方式输出(非递归法)  用两个栈实现
188 void postOrder02(BiTree T)
189 {
190     stack <BiTree> sta;
191     stack <BiTree> sta2;
192     if( T == NULL)
193     {
194         return;
195     }
196 
197     sta.push(T);
198     while(sta.empty() != true)
199     {
200         T = sta.top();
201         sta.pop();
202         sta2.push(T);
203         if(T->lchild != NULL)
204         {
205             sta.push(T->lchild);
206         }
207         if(T->rchild != NULL)
208         {
209             sta.push(T->rchild);
210         }
211     }
212 
213     while(sta2.empty() != true)
214     {
215         BiTree temp = sta2.top();
216         cout<< temp->data <<' ';
217         sta2.pop();
218     }
219 
220 
221 }
222 //后序遍历方式输出(非递归法)  用1个栈实现
223 //这里回退的时候,必须知道知否遍历过了,要有标识
224 void postOrder03(BiTree T)
225 {
226     stack <BiTree> sta;
227     
228     if( T == NULL)
229     {
230         return;
231     }
232 
233     sta.push(T);
234     BiTree temp = T;
235     while(sta.empty() != true)
236     {
237         T = sta.top();
238         if(T->lchild != NULL  && temp != T->lchild && temp != T->rchild)
              //if(T->lchild != NULL  && temp != T->lchild ) 上面的如果不加另一个约束项会陷入无限的循环
239 { 240 sta.push(T->lchild); 241 } 242 else if (T->rchild != NULL && temp != T->rchild) 243 { 244 sta.push(T->rchild); 245 } 246 else 247 { 248 sta.pop(); 249 temp = T; 250 cout<< T->data << ' '; 251 } 252 } 253 254 } 255 256 int main() 257 { 258 BiTree Tr;// 259 //Tree->lchild = Tree->rchild = NULL; 加上这样子的句子 也不对 260 //BiTree Tr = {'\0'}; 261 //Tr=(BiTree)malloc(sizeof(BiNode)); 262 createPreBst(Tr); 263 postOrder02(Tr); //这种也会引发值传递和地址传递的情况,但是由于打印语句是在函数中,所以结果是对的,但是有隐患。 264 system("pause"); 265 }

 

 

 这里面有很多的盲点,比如stl中栈的empty()返回的是真。

在结构体中不能声明结构体类型的变量,但可以声明结构体类型的指针(这个与分不分配内存有关系)

posted @ 2018-03-04 16:02  小陈同学啦  阅读(357)  评论(0编辑  收藏  举报