關於二叉樹的遍歷,遞歸遍歷的話,就只要不斷的遞歸就夠啦,而非遞歸的話就須要用到棧和隊列了,然而棧和隊列也是我本身寫的吧,就算是鍛鍊了一下本身對數據結構課的掌握吧,而非遞歸後序遍歷二叉樹參考了http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。html
1、先序遍歷二叉樹node
1.遞歸遍歷c#
每次先判斷是否爲空樹,若不是則訪問根節點,而後左子樹,最後右子樹。數據結構
1 /*二叉樹遞歸先序遍歷*/ 2 void PreTraverseTree1(TreeNode * T) 3 { 4 if(T) 5 { 6 printf("%c ", T->data) ; 7 PreTraverseTree1(T->leftchild) ; 8 PreTraverseTree1(T->rightchild) ; 9 } 10 }
2.非遞歸遍歷函數
判斷棧是否爲空或子樹爲空,若不爲空,就訪問左孩子入棧,直至左孩子爲空,若左孩子爲空,就出棧,而後訪問右孩子,入棧,就這樣不斷的循環。spa
1 /*二叉樹的非遞歸先序遍歷*/ 2 void PreTraverseTree2(TreeNode * T) 3 { 4 StackNode * S ; 5 TreeNode * p ; 6 S = NULL ; 7 p = T ; 8 S = InitStack(S) ; 9 10 if(NULL == p) 11 { 12 printf("樹爲空!\n") ; 13 return ; 14 } 15 16 while(p || !StackEmpty(S)) 17 { 18 if(p) 19 { 20 StackPush(S, p) ; 21 printf("%c ", p->data) ; 22 p = p->leftchild ; 23 } 24 else 25 { 26 StackPop(S, p) ; 27 p = p->rightchild ; 28 } 29 } 30 31 free(S) ; 32 }
2、中序遍歷二叉樹code
1.遞歸遍歷htm
每次先判斷樹是否爲空,若不爲空,則訪問左子樹,而後根子樹,最後右子樹。blog
1 /*二叉樹遞歸中序遍歷*/ 2 void InOrderTraverseTree1(TreeNode * T) 3 { 4 if(T) 5 { 6 InOrderTraverseTree1(T->leftchild) ; 7 printf("%c ", T->data) ; 8 InOrderTraverseTree1(T->rightchild) ; 9 } 10 }
2.非遞歸遍歷遞歸
思路基本和先序差很少,只是輸出數據的時候不同。判斷棧和樹是否爲空,若不,則判斷樹是否爲空,不爲繼續將左子樹進棧,若爲空,則出棧,輸出數據,而後訪問右子樹。
1 /*二叉樹的非遞歸中序遍歷*/ 2 void InOrderTraverseTree2(TreeNode * T) 3 { 4 StackNode * S ; 5 TreeNode * p ; 6 S = NULL ; 7 p = T ; 8 S = InitStack(S) ; 9 10 if(NULL == p) 11 { 12 printf("樹爲空!\n") ; 13 return ; 14 } 15 16 while(p || !StackEmpty(S)) 17 { 18 if(p) 19 { 20 StackPush(S, p) ; 21 p = p->leftchild ; 22 } 23 else 24 { 25 StackPop(S, p) ; 26 printf("%c ", p->data) ; 27 p = p->rightchild ; 28 } 29 } 30 free(S) ; 31 }
3、後序遍歷二叉樹
1.遞歸遍歷
先判斷樹是否爲空,若不爲,先左子樹,後右子樹,而後根節點。
1 /*二叉樹遞歸後序遍歷*/ 2 void LastTraverseTree1(TreeNode * T) 3 { 4 if(T) 5 { 6 LastTraverseTree1(T->leftchild) ; 7 LastTraverseTree1(T->rightchild) ; 8 printf("%c ", T->data) ; 9 } 10 }
2.非遞歸遍歷
要保證根結點在左孩子和右孩子訪問以後才能訪問,所以對於任一結點P,先將其入棧。若是P不存在左孩子和右孩子,則能夠直接訪問它;或者P存在左孩子或者右孩子,可是其左孩子和右孩子都已被訪問過了,則一樣能夠直接訪問該結點。若非上述兩種狀況,則將P的右孩子和左孩子依次入棧,這樣就保證了每次取棧頂元素的時候,左孩子在右孩子前面被訪問,左孩子和右孩子都在根結點前面被訪問。
1 /*二叉樹非遞歸後序遍歷*/ 2 void LastTraverseTree2(TreeNode * T) 3 { 4 StackNode * S ; 5 TreeNode * cur, * pre ; 6 S = NULL ; 7 S = InitStack(S) ; 8 if(NULL == T) 9 { 10 printf("樹爲空!\n") ; 11 return ; 12 } 13 14 pre = NULL ; cur = NULL ; 15 StackPush(S,T) ; 16 while(!StackEmpty(S)) 17 { 18 cur = NULL ; 19 StackGetTop(S,cur) ; 20 if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild))) 21 { 22 printf("%c ", cur->data) ; 23 pre = cur ; 24 StackPop(S,cur) ; 25 } 26 else 27 { 28 if(cur->rightchild != NULL) 29 { 30 StackPush(S,cur->rightchild) ; 31 } 32 if(cur->leftchild != NULL) 33 { 34 StackPush(S,cur->leftchild) ; 35 } 36 } 37 } 38 free(S) ; 39 }
4、層次遍歷二叉樹
創建一個隊列,先將根節點入隊,而後將隊首出隊,而後判斷它的左右子樹是否爲空,不爲空,則先將左子樹入隊,而後右子樹入隊。
1 /*二叉樹層次遍歷*/ 2 void LevelTraverseTree(TreeNode * T) 3 { 4 QueueHead * Q ; 5 TreeNode * p ; 6 Q = NULL ; p = T ; 7 Q = InitQueue(Q) ; 8 if(NULL == p) 9 { 10 printf("樹爲空!\n") ; 11 return ; 12 } 13 14 QueuePush(Q,p) ; 15 while(!QueueEmpty(Q)) 16 { 17 p = NULL ; 18 QueuePop(Q,p) ; 19 20 if(NULL != p->leftchild) 21 QueuePush(Q,p->leftchild) ; 22 23 if(NULL != p->rightchild) 24 QueuePush(Q,p->rightchild) ; 25 26 printf("%c ", p->data) ; 27 } 28 }
貼上我本身的所有代碼,本身之後能夠看,但願或許對別人也有幫助吧,表達能力不行,嘿嘿。
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 typedef struct treenode //樹的節點 5 { 6 char data ; 7 treenode * leftchild, * rightchild ; 8 }TreeNode; 9 10 typedef TreeNode * StackElemType ; //定義棧包含的數據類型 11 12 typedef struct stacknode //棧的節點 13 { 14 StackElemType data ; 15 stacknode * next ; 16 }StackNode; 17 18 typedef TreeNode * QueueElemType ; //定義隊列包含的數據類型 19 20 typedef struct queuenode //定義隊列節點 21 { 22 QueueElemType data ; 23 struct queuenode * next ; 24 }QueueNode; 25 26 typedef struct queuehead //定義隊列的頭節點 27 { 28 QueueNode * front, * rear ; 29 }QueueHead; 30 31 //stack的有關聲明 32 StackNode * InitStack(StackNode * S) ; 33 void StackPush(StackNode * S, StackElemType data) ; 34 void StackPop(StackNode * S, StackElemType & data) ; 35 int StackEmpty(StackNode * S) ; 36 int StackGetTop(StackNode * S, StackElemType & data) ; 37 38 //queue的有關聲明 39 QueueHead * InitQueue(QueueHead * Q) ; 40 void QueuePush(QueueHead * Q, QueueElemType data) ; 41 void QueuePop(QueueHead * Q, QueueElemType & data) ; 42 int QueueEmpty(QueueHead * Q) ; 43 44 //TreeTraverse的有關聲明 45 TreeNode * InitTree(TreeNode * T) ; 46 void PreTraverseTree1(TreeNode * T) ; 47 void PreTraverseTree2(TreeNode * T) ; 48 void InOrderTraverseTree1(TreeNode * T) ; 49 void InOrderTraverseTree2(TreeNode * T) ; 50 void LastTraverseTree1(TreeNode * T) ; 51 void LastTraverseTree2(TreeNode * T) ; 52 void LevelTraverseTree(TreeNode * T) ; 53 54 //棧的函數定義 55 StackNode * InitStack(StackNode * S) 56 { 57 S = (StackNode *)malloc(sizeof(StackNode)) ; 58 if(NULL == S) 59 { 60 printf("內存不足,不能分配棧!\n") ; 61 exit(0) ; 62 } 63 64 S->next = NULL ; 65 return(S) ; 66 } 67 68 void StackPush(StackNode * S, StackElemType data) 69 { 70 StackNode * q ; 71 q = (StackNode *)malloc(sizeof(StackNode)) ; 72 if(NULL == q) 73 { 74 printf("內存不足,不能分配棧!\n") ; 75 exit(0) ; 76 } 77 q->data = data ; 78 q->next = S->next ; 79 S->next = q ; 80 } 81 82 void StackPop(StackNode * S, StackElemType & data) 83 { 84 StackNode * q ; 85 if(NULL == S->next) 86 { 87 printf("棧爲空,無返回值!\n") ; 88 } 89 90 q = S->next ; 91 data = q->data ; 92 S->next = q->next ; 93 free(q) ; 94 } 95 96 int StackEmpty(StackNode * S) 97 { 98 if(NULL == S->next) 99 { 100 return(1) ; 101 } 102 103 return(0) ; 104 } 105 106 int StackGetTop(StackNode * S, StackElemType & data) 107 { 108 if(NULL != S->next) 109 { 110 data = S->next->data ; 111 return(1) ; 112 } 113 else 114 { 115 //data = NULL ; 116 return(0) ; 117 } 118 } 119 120 121 //隊列函數的定義 122 QueueHead * InitQueue(QueueHead * Q) 123 { 124 QueueNode * q ; 125 Q = (QueueHead *)malloc(sizeof(QueueHead)) ; 126 if(NULL == Q) 127 { 128 printf("內存不足!\n") ; 129 exit(0) ; 130 } 131 q = (QueueNode *)malloc(sizeof(QueueNode)) ; 132 if(NULL == q) 133 { 134 printf("內存不足!\n") ; 135 exit(0) ; 136 } 137 138 q->next = NULL ; 139 Q->front = q ; 140 Q->rear = q ; 141 142 return(Q) ; 143 } 144 145 void QueuePush(QueueHead * Q, QueueElemType data) 146 { 147 QueueNode * q ; 148 q = (QueueNode *)malloc(sizeof(QueueNode)) ; 149 if(NULL == q) 150 { 151 printf("內存不足!\n") ; 152 exit(0) ; 153 } 154 155 q->data = data ; 156 q->next = Q->rear->next ; 157 Q->rear->next = q ; 158 Q->rear = q ; 159 } 160 161 void QueuePop(QueueHead * Q, QueueElemType & data) 162 { 163 QueueNode * q ; 164 if(Q->front == Q->rear) 165 { 166 printf("隊列爲空!\n") ; 167 return ; 168 } 169 170 q = Q->front->next ; 171 data = q->data ; 172 Q->front->next = q->next ; 173 if(Q->rear == q) 174 Q->rear = Q->front ; 175 176 free(q) ; 177 } 178 179 int QueueEmpty(QueueHead * Q) 180 { 181 if(Q->front == Q->rear) 182 return(1) ; 183 else 184 return(0) ; 185 } 186 187 188 //樹的各類遍歷函數定義 189 190 /*創建一棵二叉樹*/ 191 TreeNode * InitTree(TreeNode * T) 192 { 193 char data ; 194 scanf("%c", &data) ; 195 196 if('#' == data) 197 { 198 T = NULL ; 199 } 200 else 201 { 202 T = (TreeNode *)malloc(sizeof(TreeNode)) ; 203 T->data = data ; 204 T->leftchild = InitTree(T->leftchild) ; 205 T->rightchild = InitTree(T->rightchild) ; 206 } 207 208 return(T) ; 209 } 210 211 /*二叉樹遞歸先序遍歷*/ 212 void PreTraverseTree1(TreeNode * T) 213 { 214 if(T) 215 { 216 printf("%c ", T->data) ; 217 PreTraverseTree1(T->leftchild) ; 218 PreTraverseTree1(T->rightchild) ; 219 } 220 } 221 222 /*二叉樹的非遞歸先序遍歷*/ 223 void PreTraverseTree2(TreeNode * T) 224 { 225 StackNode * S ; 226 TreeNode * p ; 227 S = NULL ; 228 p = T ; 229 S = InitStack(S) ; 230 231 if(NULL == p) 232 { 233 printf("樹爲空!\n") ; 234 return ; 235 } 236 237 while(p || !StackEmpty(S)) 238 { 239 if(p) 240 { 241 StackPush(S, p) ; 242 printf("%c ", p->data) ; 243 p = p->leftchild ; 244 } 245 else 246 { 247 StackPop(S, p) ; 248 p = p->rightchild ; 249 } 250 } 251 252 free(S) ; 253 } 254 255 /*二叉樹遞歸中序遍歷*/ 256 void InOrderTraverseTree1(TreeNode * T) 257 { 258 if(T) 259 { 260 InOrderTraverseTree1(T->leftchild) ; 261 printf("%c ", T->data) ; 262 InOrderTraverseTree1(T->rightchild) ; 263 } 264 } 265 266 /*二叉樹的非遞歸中序遍歷*/ 267 void InOrderTraverseTree2(TreeNode * T) 268 { 269 StackNode * S ; 270 TreeNode * p ; 271 S = NULL ; 272 p = T ; 273 S = InitStack(S) ; 274 275 if(NULL == p) 276 { 277 printf("樹爲空!\n") ; 278 return ; 279 } 280 281 while(p || !StackEmpty(S)) 282 { 283 if(p) 284 { 285 StackPush(S, p) ; 286 p = p->leftchild ; 287 } 288 else 289 { 290 StackPop(S, p) ; 291 printf("%c ", p->data) ; 292 p = p->rightchild ; 293 } 294 } 295 free(S) ; 296 } 297 298 /*二叉樹遞歸後序遍歷*/ 299 void LastTraverseTree1(TreeNode * T) 300 { 301 if(T) 302 { 303 LastTraverseTree1(T->leftchild) ; 304 LastTraverseTree1(T->rightchild) ; 305 printf("%c ", T->data) ; 306 } 307 } 308 309 /*二叉樹非遞歸後序遍歷*/ 310 void LastTraverseTree2(TreeNode * T) 311 { 312 StackNode * S ; 313 TreeNode * cur, * pre ; 314 S = NULL ; 315 S = InitStack(S) ; 316 if(NULL == T) 317 { 318 printf("樹爲空!\n") ; 319 return ; 320 } 321 322 pre = NULL ; cur = NULL ; 323 StackPush(S,T) ; 324 while(!StackEmpty(S)) 325 { 326 cur = NULL ; 327 StackGetTop(S,cur) ; 328 if((cur->leftchild == NULL && cur->rightchild == NULL) || (pre != NULL && (pre == cur->leftchild ||pre == cur->rightchild))) 329 { 330 printf("%c ", cur->data) ; 331 pre = cur ; 332 StackPop(S,cur) ; 333 } 334 else 335 { 336 if(cur->rightchild != NULL) 337 { 338 StackPush(S,cur->rightchild) ; 339 } 340 if(cur->leftchild != NULL) 341 { 342 StackPush(S,cur->leftchild) ; 343 } 344 } 345 } 346 free(S) ; 347 } 348 349 /*二叉樹層次遍歷*/ 350 void LevelTraverseTree(TreeNode * T) 351 { 352 QueueHead * Q ; 353 TreeNode * p ; 354 Q = NULL ; p = T ; 355 Q = InitQueue(Q) ; 356 if(NULL == p) 357 { 358 printf("樹爲空!\n") ; 359 return ; 360 } 361 362 QueuePush(Q,p) ; 363 while(!QueueEmpty(Q)) 364 { 365 p = NULL ; 366 QueuePop(Q,p) ; 367 368 if(NULL != p->leftchild) 369 QueuePush(Q,p->leftchild) ; 370 371 if(NULL != p->rightchild) 372 QueuePush(Q,p->rightchild) ; 373 374 printf("%c ", p->data) ; 375 } 376 } 377 378 379 //主函數的定義 380 void Tips() 381 { 382 printf("創建樹是按照先序遍從來創建樹的,而且輸入‘#’表示子樹爲空。\n") ; 383 printf("請輸入要創建的樹:") ; 384 } 385 386 int main() 387 { 388 TreeNode * T ; 389 T = NULL ; 390 391 Tips() ; 392 393 T = InitTree(T) ; 394 395 printf("二叉樹遞歸先序遍歷\n") ; 396 PreTraverseTree1(T) ; 397 printf("\n") ; 398 399 printf("二叉樹非遞歸先序遍歷\n") ; 400 PreTraverseTree2(T) ; 401 printf("\n") ; 402 403 printf("二叉樹遞歸中序遍歷\n") ; 404 InOrderTraverseTree1(T) ; 405 printf("\n") ; 406 407 printf("二叉樹非遞歸中序遍歷\n") ; 408 InOrderTraverseTree2(T) ; 409 printf("\n") ; 410 411 printf("二叉樹遞歸後序遍歷\n") ; 412 LastTraverseTree1(T) ; 413 printf("\n") ; 414 415 printf("二叉樹非遞歸後序遍歷\n") ; 416 LastTraverseTree2(T) ; 417 printf("\n") ; 418 419 printf("二叉樹層次遍歷\n") ; 420 LevelTraverseTree(T) ; 421 printf("\n") ; 422 423 return 0 ; 424 }
給一個二叉樹參考例子:
a
b c
d e
輸入:abd##e##c##
輸出:
二叉樹先序遞歸遍歷:a b d e c
二叉樹先序非遞歸遍歷:a b d e c
二叉樹中序遞歸遍歷:d b e a c
二叉樹中序非遞歸遍歷:d b e a c
二叉樹後序遞歸遍歷:d e b c a
二叉樹後序非遞歸遍歷:d e b c a
二叉樹層次遍歷:a b c d e