1 //按照先序序列輸入構建一棵二叉樹 2 void Create(BiTree &T) 3 { 4 char ch; 5 scanf("%c",&ch); 6 if( '#' == ch ) 7 { 8 T = NULL; 9 } 10 else 11 { 12 T=(BiNode *)malloc(sizeof(BiNode)); 13 T->data=ch; 14 Create(T->lchild); 15 Create(T->rchild); 16 } 17 }
二叉樹的遞歸遍歷算法node
1 //二叉樹的先序遍歷 2 3 void PreOrder(BiTree T) 4 5 { 6 7 if(T) 8 9 { 10 11 printf( "%c ",T->data); 12 13 PreOrder(T->lchild); 14 15 PreOrder(T->rchild); 16 17 } 18 19 } 20 21 //二叉樹的中序遍歷 22 23 void InOrder(BiTree T) 24 25 { 26 27 if(T) 28 29 { 30 31 InOrder(T->lchild); 32 33 printf( "%c ",T->data); 34 35 InOrder(T->rchild); 36 37 } 38 39 } 40 41 42 43 //二叉樹的後序遍歷 44 45 void PostOrder(BiTree T) 46 47 { 48 49 if(T) 50 51 { 52 53 PostOrder(T->lchild); 54 55 PostOrder(T->rchild); 56 57 printf( "%c ",T->data); 58 59 } 60 61 }
/* 設置一個存放結點指針的棧 S ,從根結點開始,每訪問一結點後,按先序規則走左子樹,若右子樹存在, 則將右子樹指針進棧,以便之後能正確地返回到該右子樹上進行遍歷訪問。 */ void PreTraverse(BiTree T) { BiNode *p; Stack S; S=InitStack(); if (T) { Push(S,T); // 根結點指針進棧 while (!StackEmpty(S)) { p=Pop(S); // 出棧,棧頂元素賦給 p while (p) { printf( "%c\t" ,p->data); // 訪問 p結點 if (p->rchild) Push(S,p->rchild); // 右子樹存在時,進棧 p=p->lchild; // 繼續沿着左子樹往下走 } } } }
/*web
/* 同前序遍歷 , 棧S 存放結點指針。對每棵子樹 ( 開始是整棵二叉樹 ),沿左找到該子樹在中序下的第一結點 ( 但尋找路徑上的每一個結點指針要進棧 ), 訪問之; 而後遍歷該結點的右子樹 , 又尋找該子樹在中序下的第一結點, .. …直到棧S 空爲止。 */ void InTraverse(BiTree T) { BiNode *p; Stack S; S=InitStack(); Push(S,T); // 根結點指針進棧 while (!StackEmpty(S)) { while ((p=GetsTop(S))&&p) //取棧頂元素且存在,賦給 p Push(S,p->lchild); //p 的左子樹進棧 p=Pop(S); // 去掉最後的空指針 if (!StackEmpty(S)) { p=Pop(S); // 彈出棧頂元素,賦給 p printf( "%c\t" ,p->data); // 訪問 p結點 Push(S,p->rchild); // 右子樹進棧,而後遍歷右子樹 } } }
/*算法
/* 對一個結點是否能訪問,要看他的左、右子樹是否遍歷完, */ /* 因此每個結點對應一個標誌位 -tag 。tag=0 ,表示該結點暫不能訪問; tag=1 ,表示該結點能夠訪問 */ /* 實際上是區分此次返回是遍歷完左子樹返回的仍是遍歷完右子樹返回的,若是是左子樹返回的那麼就不能訪問根結點, */ /* 若是是右子樹返回的就能訪問根結點。當搜索到某 P 結點時,先要遍歷其左子樹,於是將結點地址 P 及tag=0 進棧; */ /* 當P 結點的左子樹遍歷完以後,再遍歷其右子樹,又將地址 P 及tag=1 進棧;當 P結點右子樹遍歷完以後( tag=1 ),即可對 P結點進行訪問 */ void PostTraverse(BiTree T) { int tag; BiNode *p; Stacks S; SNode sdata; S=InitStacks(); p=T; while (p||!StacksEmpty(S)) { while (p) { sdata.q=p; sdata.tag=0; Pushs(S,&sdata); //(p,0) 進棧 p=p->lchild; // 遍歷p 之左子樹 } sdata=*Pops(S); // 退棧 p=sdata.q; // 取指針 tag=sdata.tag; // 狀態位 if (tag==0) //從左子樹返回時,根的 tag=0 { sdata.q=p; sdata.tag=1; // 這時要進入根的右子樹了,因此根的 tag=1 ,下次碰到根時就能夠訪問了 Pushs(S,&sdata); //(p,1) 進棧,根還得進一次棧 p=p->rchild; // 遍歷右子樹 } else //tag=1,這是說明了右子樹訪問完了返回,因此此次要對根進行訪問了 { printf( "%c\t" ,p->data); p=NULL; } } }
// 二叉樹的層次遍歷 void LevelTraverse(BiTree T) { BiNode *p; LinkQueue *Q; InitQueue(Q); EnQueue(Q,T); while (!QueueEmpty(Q)) { p=DeQueue(Q); printf( "%c\t" ,p->data); if (p->lchild!=NULL) EnQueue(Q,p->lchild); if (p->rchild!=NULL) EnQueue(Q,p->rchild); } }
1 #include <stdio.h> 2 3 #include <stdlib.h> 4 5 #include <string.h> 6 7 #include "treenode.h" 8 9 #include "mystack.h" 10 11 #include "myqueue.h" 12 13 #include "newstack.h" 14 15 16 17 //按照先序序列輸入構建一棵二叉樹 18 19 void Create(BiTree &T) 20 21 { 22 23 char ch; 24 25 scanf( "%c",&ch); 26 27 if( '#' == ch ) 28 29 { 30 31 T = NULL; 32 33 } 34 35 else 36 37 { 38 39 T=(BiNode *)malloc( sizeof(BiNode)); 40 41 T->data=ch; 42 43 Create(T->lchild); 44 45 Create(T->rchild); 46 47 } 48 49 } 50 51 52 53 //二叉樹的先序遍歷 54 55 void PreOrder(BiTree T) 56 57 { 58 59 if(T) 60 61 { 62 63 printf( "%c ",T->data); 64 65 PreOrder(T->lchild); 66 67 PreOrder(T->rchild); 68 69 } 70 71 } 72 73 74 75 //二叉樹先序遍歷的非遞歸算法 76 77 void PreTraverse(BiTree T) 78 79 { 80 81 BiNode *p; 82 83 Stack S; 84 85 S=InitStack(); 86 87 if(T) 88 89 { 90 91 Push(S,T); //根結點指針進棧 92 93 while(!StackEmpty(S)) 94 95 { 96 97 p=Pop(S); //出棧,棧頂元素賦給p 98 99 while(p) 100 101 { 102 103 printf( "%c\t",p->data); // 訪問p結點 104 105 if(p->rchild) 106 107 Push(S,p->rchild); //右子樹存在時,進棧 108 109 p=p->lchild; //繼續沿着左子樹往下走 110 111 } 112 113 } 114 115 } 116 117 } 118 119 120 121 //二叉樹的中序遍歷 122 123 void InOrder(BiTree T) 124 125 { 126 127 if(T) 128 129 { 130 131 InOrder(T->lchild); 132 133 printf( "%c ",T->data); 134 135 InOrder(T->rchild); 136 137 } 138 139 } 140 141 142 143 //二叉樹的中序遍歷的非遞歸算法 144 145 void InTraverse(BiTree T) 146 147 { 148 149 BiNode *p; 150 151 Stack S; 152 153 S=InitStack(); 154 155 Push(S,T); //根結點指針進棧 156 157 while(!StackEmpty(S)) 158 159 { 160 161 while((p=GetsTop(S))&&p) //取棧頂元素且存在,賦給 p 162 163 Push(S,p->lchild); //p的左子樹進棧 164 165 p=Pop(S); //去掉最後的空指針 166 167 if(!StackEmpty(S)) 168 169 { 170 171 p=Pop(S); //彈出棧頂元素,賦給p 172 173 printf( "%c\t",p->data); // 訪問p結點 174 175 Push(S,p->rchild); //右子樹進棧,而後遍歷右子樹 176 177 } 178 179 } 180 181 } 182 183 184 185 //二叉樹的後序遍歷 186 187 void PostOrder(BiTree T) 188 189 { 190 191 if(T) 192 193 { 194 195 PostOrder(T->lchild); 196 197 PostOrder(T->rchild); 198 199 printf( "%c ",T->data); 200 201 } 202 203 } 204 205 206 207 void PostTraverse(BiTree T) 208 209 { 210 211 int tag; 212 213 BiNode *p; 214 215 Stacks S; 216 217 SNode sdata; 218 219 S=InitStacks(); 220 221 p=T; 222 223 while(p||!StacksEmpty(S)) 224 225 { 226 227 while(p) 228 229 { 230 231 sdata.q=p; 232 233 sdata.tag=0; 234 235 Pushs(S,&sdata); //(p,0)進棧 236 237 p=p->lchild; //遍歷p 之左子樹 238 239 } 240 241 sdata=*Pops(S); //退棧 242 243 p=sdata.q; //取指針 244 245 tag=sdata.tag; //狀態位 246 247 if(tag==0) //從左子樹返回時,根的 tag=0 248 249 { 250 251 sdata.q=p; 252 253 sdata.tag=1; //這時要進入根的右子樹了,因此根的 tag=1,下次碰到根時就能夠訪問了 254 255 Pushs(S,&sdata); //(p,1)進棧,根還得進一次棧 256 257 p=p->rchild; //遍歷右子樹 258 259 } 260 261 else //tag=1,這是說明了右子樹訪問完了返回,因此此次要對根進行訪問了 262 263 { 264 265 printf( "%c\t",p->data); 266 267 p=NULL; 268 269 } 270 271 } 272 273 } 274 275 276 277 //二叉樹的層次遍歷 278 279 void LevelTraverse(BiTree T) 280 281 { 282 283 BiNode *p; 284 285 LinkQueue *Q; 286 287 InitQueue(Q); 288 289 EnQueue(Q,T); 290 291 while(!QueueEmpty(Q)) 292 293 { 294 295 p=DeQueue(Q); 296 297 printf( "%c\t",p->data); 298 299 if(p->lchild!=NULL) 300 301 EnQueue(Q,p->lchild); 302 303 if(p->rchild!=NULL) 304 305 EnQueue(Q,p->rchild); 306 307 } 308 309 } 310 311 312 313 int main() 314 315 { 316 317 BiTree T; 318 319 Create(T); 320 321 PostOrder(T); 322 323 printf( "\n"); 324 325 LevelTraverse(T); 326 327 printf( "\n"); 328 329 PostTraverse(T); 330 331 printf( "\n"); 332 333 334 335 return 0; 336 337 }