关于二叉树的遍历,递归遍历的话,就只要不断的递归就够啦,而非递归的话就需要用到栈和队列了,然而栈和队列也是我自己写的吧,就算是锻炼了一下自己对数据结构课的掌握吧,而非递归后序遍历二叉树参考了http://www.cnblogs.com/dolphin0520/archive/2011/08/25/2153720.html的思路。
一、先序遍历二叉树
1.递归遍历
每次先判断是否为空树,若不是则访问根节点,然后左子树,最后右子树。
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.非递归遍历
判断栈是否为空或子树为空,若不为空,就访问左孩子入栈,直至左孩子为空,若左孩子为空,就出栈,然后访问右孩子,入栈,就这样不断的循环。
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("树为空! ") ; 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 }
二、中序遍历二叉树
1.递归遍历
每次先判断树是否为空,若不为空,则访问左子树,然后根子树,最后右子树。
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("树为空! ") ; 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 }
三、后序遍历二叉树
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("树为空! ") ; 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 }
四、层次遍历二叉树
建立一个队列,先将根节点入队,然后将队首出队,然后判断它的左右子树是否为空,不为空,则先将左子树入队,然后右子树入队。
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("树为空! ") ; 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("内存不足,不能分配栈! ") ; 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("内存不足,不能分配栈! ") ; 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("栈为空,无返回值! ") ; 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("内存不足! ") ; 129 exit(0) ; 130 } 131 q = (QueueNode *)malloc(sizeof(QueueNode)) ; 132 if(NULL == q) 133 { 134 printf("内存不足! ") ; 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("内存不足! ") ; 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("队列为空! ") ; 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("树为空! ") ; 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("树为空! ") ; 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("树为空! ") ; 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("树为空! ") ; 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("建立树是按照先序遍历来建立树的,并且输入‘#’表示子树为空。 ") ; 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("二叉树递归先序遍历 ") ; 396 PreTraverseTree1(T) ; 397 printf(" ") ; 398 399 printf("二叉树非递归先序遍历 ") ; 400 PreTraverseTree2(T) ; 401 printf(" ") ; 402 403 printf("二叉树递归中序遍历 ") ; 404 InOrderTraverseTree1(T) ; 405 printf(" ") ; 406 407 printf("二叉树非递归中序遍历 ") ; 408 InOrderTraverseTree2(T) ; 409 printf(" ") ; 410 411 printf("二叉树递归后序遍历 ") ; 412 LastTraverseTree1(T) ; 413 printf(" ") ; 414 415 printf("二叉树非递归后序遍历 ") ; 416 LastTraverseTree2(T) ; 417 printf(" ") ; 418 419 printf("二叉树层次遍历 ") ; 420 LevelTraverseTree(T) ; 421 printf(" ") ; 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