二叉樹的三種遍歷


前言:搞懂非遞歸和遞歸三種遍歷,二叉樹的90%的問題算你全搞定了。

先序遍歷:根,左子樹,右子樹

中序遍歷:左子樹,根,右子樹

后序遍歷:左子樹,右子樹,根

先序遍歷序列的特點:ABCDEFGHIJK  A是樹根,左子樹可能是BCDEFGH右子樹可能是IJK  對於B左子樹可能是CD,右子樹可能是EFGH。即,任一結點,它的右側的一段元素依次是左子樹,右子樹。

中序遍歷序列的特點:ABCDEFGHIJK   對任一結點,左側一段是它的左子樹,右側一段是它的右子樹。

后序遍歷序列的特點:ABCDEFGHIJK  K是樹根,對於任一結點,左側一段結點,從左向右依次是左子樹,右子樹。

根據先序中序 或 后序中序 能還原一棵二叉樹,根據 先序和后序 不能還原一棵二叉樹。

遞歸遍歷:

 24 /*先序遞歸遍歷*/
 25 void DLR(BiTree *T) {
 26     if(*T != NULL) {
 27         printf("%c ",(*T)->data);
 28         DLR(&(*T)->lchild);
 29         DLR(&(*T)->rchild);
 30     }
 31 }
 32 /*中序遞歸遍歷*/
 33 void LDR(BiTree *T) {
 34     if(*T != NULL) {
 35         LDR(&(*T)->lchild);
 36         printf("%c  ",(*T)->data);
 37         LDR(&(*T)->rchild);
 38     }
 39 }
 40 
 41 /*后序遞歸遍歷*/
 42 void LRD(BiTree *T) {
 43     if(*T == NULL)
 44         return;
 45     LRD(&(*T)->lchild);
 46     LRD(&(*T)->rchild);
 47     printf("%c ",(*T)->data);
 48 }

非遞歸遍歷

 

 1 /*非遞歸中序遍歷*/
 2 void LDR_no_recursion(BiTree *T) {
 3     BiTree stack[100];
 4     int top = -1;
 5     if (*T == null)
 6         return;
 7     BiTree p = *T;
 8     while (p) {
 9         stack[++top] = p;
10         p = p->lchild;
11     }
12     while (top != -1) {
13         while (top != -1 && stack[top]->rchild == null){
14             p = stack[top];
15             printf("%c ",p->data);
16             --top;
17         }
18         if (top == -1)
19             return;
20         else {
21             p = stack[top]->rchild;
22             printf("%c ", stack[top]->data);
23             --top;
24             while (p) {
25                 stack[++top] = p;
26                 p = p->lchild;
27             }
28         }
29     }
30 }
31 /*后序非遞歸遍歷*/
32 void LRD_no_recursion(BiTree *T) {
33     
34     if (*T == null)
35         return;
36     SBiTNode st;
37     SBiTNode stack[100];//總是忘記帶*
38     int top = -1;
39     BiTree p = *T; 
40     while (p) {
41         top++;
42         stack[top].elem = p;
43         stack[top].flag = 0;
44         p = p->lchild;
45     }
46     while (top != -1) {
47         st = stack[top];
48         if (st.elem->rchild == null || st.flag == 1) {
49             printf("%c ", st.elem->data);
50             --top;
51         }
52         else {
53             stack[top].flag = 1;
54             p = st.elem->rchild;
55             while (p) {
56                 top++;
57                 stack[top].elem = p;
58                 stack[top].flag = 0;
59                 p = p->lchild;
60             }
61         }
62     }
63 }
View Code

三種遍歷完整源代碼

  1 #include"頭文件.h"
  2 
  3 typedef struct node {
  4     char data;
  5     struct node *lchild, *rchild;
  6 }BiTNode,*BiTree;
  7 
  8 typedef struct {
  9     BiTree elem;
 10     int flag;
 11 }SBiTNode;//棧結點
 12 
 13 /*先序創建二叉樹*/
 14 void CreateTree(BiTree *T) {
 15     char ch;
 16     scanf_s("%c", &ch);
 17     if (ch == '#') {
 18         *T = null;
 19     }
 20     else {
 21         *T = (BiTree)malloc(sizeof(BiTNode));
 22         if (*T == null) exit(-1);
 23         (*T)->data = ch;
 24         CreateTree(&(*T)->lchild);
 25         CreateTree(&(*T)->rchild);
 26     }
 27 }
 28 /*先序遞歸遍歷*/
 29 void DLR(BiTree *T) {
 30     if (*T) {
 31         printf("%c ", (*T)->data);
 32         DLR(&(*T)->lchild);
 33         DLR(&(*T)->rchild);
 34     }
 35 }
 36 /*中序遞歸遍歷*/
 37 void LDR(BiTree *T) {
 38     if (*T) {
 39         LDR(&(*T)->lchild);
 40         printf("%c ", (*T)->data);
 41         LDR(&(*T)->rchild);
 42     }
 43 }
 44 /*非遞歸中序遍歷*/
 45 void LDR_no_recursion(BiTree *T) {
 46     BiTree stack[100];
 47     int top = -1;
 48     if (*T == null)
 49         return;
 50     BiTree p = *T;
 51     while (p) {
 52         stack[++top] = p;
 53         p = p->lchild;
 54     }
 55     while (top != -1) {
 56         while (top != -1 && stack[top]->rchild == null){
 57             p = stack[top];
 58             printf("%c ",p->data);
 59             --top;
 60         }
 61         if (top == -1)
 62             return;
 63         else {
 64             p = stack[top]->rchild;
 65             printf("%c ", stack[top]->data);
 66             --top;
 67             while (p) {
 68                 stack[++top] = p;
 69                 p = p->lchild;
 70             }
 71         }
 72     }
 73 }
 74 /*后序遍歷*/
 75 void LRD(BiTree *T) {
 76     if (*T) {
 77         LRD(&(*T)->lchild);
 78         LRD(&(*T)->rchild);
 79         printf("%c ", (*T)->data);
 80     }
 81 }
 82 /*后序非遞歸遍歷*/
 83 void LRD_no_recursion(BiTree *T) {
 84     
 85     if (*T == null)
 86         return;
 87     SBiTNode st;
 88     SBiTNode stack[100];//總是忘記帶*
 89     int top = -1;
 90     BiTree p = *T; 
 91     while (p) {
 92         top++;
 93         stack[top].elem = p;
 94         stack[top].flag = 0;
 95         p = p->lchild;
 96     }
 97     while (top != -1) {
 98         st = stack[top];
 99         if (st.elem->rchild == null || st.flag == 1) {
100             printf("%c ", st.elem->data);
101             --top;
102         }
103         else {
104             stack[top].flag = 1;
105             p = st.elem->rchild;
106             while (p) {
107                 top++;
108                 stack[top].elem = p;
109                 stack[top].flag = 0;
110                 p = p->lchild;
111             }
112         }
113     }
114 }
115 int main() {
116     BiTree T;
117     printf("創建樹:\n");
118     CreateTree(&T);
119     printf("遞歸先序遍歷:\n");
120     DLR(&T); printf("\n");
121     printf("非遞歸先序遍歷:\n");
122 
123     printf("遞歸中序遍歷:\n");
124     LDR(&T); printf("\n");
125     printf("非遞歸中序遍歷:\n");
126     LDR_no_recursion(&T); printf("\n");
127     printf("遞歸后序遍歷:\n");
128     LRD(&T); printf("\n");
129     printf("非遞歸后序遍歷:\n");
130     LRD_no_recursion(&T); printf("\n");
131 
132     system("pause");
133     return 0;
134 }
View Code

運行結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM