二叉樹的非遞歸遍歷
阿新 • • 發佈:2017-11-16
std 是否 分配 printf 棧空間 str nco 結束 oid
全部代碼
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4
5 typedef struct node
6 {
7 int nValue;
8 struct node *pLeft;
9 struct node *pRight;
10 }BiTree;
11
12 typedef struct node2
13 {
14 BiTree *nValue;
15 struct node2 *pNext;
16 }MyStack;
17
18 typedef struct node3
19 {
20 int nCount;
21 MyStack *pTop;
22 }Stack;
23
24 void s_Init(Stack **ppStack)
25 {
26 assert(ppStack != NULL);
27
28 *ppStack = (Stack *)malloc(sizeof(Stack));
29 if(NULL == *ppStack)
30 {
31 printf("棧空間分配失敗!\n ");
32 exit(-1);
33 }
34 (*ppStack)->nCount = 0;
35 (*ppStack)->pTop = NULL;
36 }
37
38 void s_Push(Stack *pStack, BiTree *nNum)
39 {
40 MyStack *pTemp = NULL;
41
42 assert(pStack != NULL);
43
44 //臨時節點開辟空間
45 pTemp = (MyStack *)malloc(sizeof(MyStack));
46 if(NULL == pTemp)
47 {
48 printf("臨時節點空間分配失敗!\n");
49 exit(-1);
50 }
51 pTemp->nValue = nNum;
52 pTemp->pNext = NULL;
53
54 //頭添加
55 //臨時節點的下一個是頭節點
56 pTemp->pNext = pStack->pTop;
57 //新節點是新棧頂
58 pStack->pTop = pTemp;
59
60 //更新棧內元素
61 ++pStack->nCount;
62 }
63
64 BiTree *s_Pop(Stack *pStack)
65 {
66 BiTree *nNum;
67 MyStack *pDel = NULL;
68
69 assert(pStack!=NULL && pStack->pTop!=NULL);
70
71 //標記 要刪除的節點
72 pDel = pStack->pTop;
73 nNum = pStack->pTop->nValue;
74 //棧頂指針下移
75 pStack->pTop = pStack->pTop->pNext;
76 //釋放空間
77 free(pDel);
78 pDel = NULL;
79
80 //更新棧內元素
81 --pStack->nCount;
82
83 return nNum;
84 }
85
86 //遞歸創建二叉樹
87 void RecCreateBiTree(BiTree **ppRoot)
88 {
89 int nNum;
90
91 assert(ppRoot!=NULL);
92
93 //輸入節點的值
94 scanf("%d", &nNum);
95
96 //檢測是否是結束標誌
97 if(0 == nNum)
98 {
99 return;
100 }
101
102 *ppRoot = (BiTree *)malloc(sizeof(BiTree));
103 if(NULL == *ppRoot)
104 {
105 printf("*ppRoot空間分配失敗!");
106 exit(-1);
107 }
108 (*ppRoot)->nValue = nNum;
109 (*ppRoot)->pLeft = NULL;
110 (*ppRoot)->pRight = NULL;
111
112 //處理當前節點的左和右
113 RecCreateBiTree(&(*ppRoot)->pLeft);
114 RecCreateBiTree(&(*ppRoot)->pRight);
115 }
116
117 //非遞歸前序遍歷
118 void UnRecPrevOrderTraversal(BiTree *pRoot)
119 {
120 Stack *pStack = NULL;
121
122 assert(pRoot!=NULL);
123
124 //申請輔助棧
125 s_Init(&pStack);
126
127 while(1)
128 {
129 //打印根 處理左
130 while(pRoot!=NULL)
131 {
132 printf("%d ", pRoot->nValue);
133 s_Push(pStack, pRoot);
134 pRoot = pRoot->pLeft;
135 }
136
137 //棧頂節點彈出 處理右子樹
138 pRoot = s_Pop(pStack);
139
140 //棧空 樹遍歷結束
141 if(NULL == pRoot)
142 {
143 return;
144 }
145
146 //處理右
147 pRoot = pRoot->pRight;
148 }
149 }
150
151 //非遞歸中序遍歷
152 void UnRecMidOrderTraversal(BiTree *pRoot)
153 {
154 Stack *pStack = NULL;
155
156 assert(pRoot!=NULL);
157
158 //申請輔助棧
159 s_Init(&pStack);
160
161 while(1)
162 {
163 //處理左
164 while(pRoot)
165 {
166 s_Push(pStack, pRoot);
167 pRoot = pRoot->pLeft;
168 }
169
170 //棧頂節點彈出
171 pRoot = s_Pop(pStack);
172
173 //棧空 樹遍歷結束
174 if(NULL == pRoot)
175 {
176 return;
177 }
178
179 //打印左
180 printf("%d ", pRoot->nValue);
181
182 //處理右
183 pRoot = pRoot->pRight;
184 }
185 }
186
187 //非遞歸後序遍歷
188 void UnRecLastOrderTraversal(BiTree *pRoot)
189 {
190 Stack *pStack = NULL;
191 BiTree *pFlag = NULL;
192
193 assert(pRoot!=NULL);
194
195 //申請輔助棧
196 s_Init(&pStack);
197
198 while(1)
199 {
200 //處理左
201 while(pRoot)
202 {
203 s_Push(pStack, pRoot);
204 pRoot = pRoot->pLeft;
205 }
206
207 //空棧 結束
208 if(NULL == pStack->pTop)
209 {
210 return;
211 }
212
213 //棧頂元素的右為空 或者已經被處理過 彈出 標記
214 if(NULL==pStack->pTop->nValue->pRight || pStack->pTop->nValue->pRight==pFlag)
215 {
216 pFlag = s_Pop(pStack);
217 printf("%d ", pFlag->nValue);
218 }
219 //未被處理過 繼續處理右
220 else
221 {
222 pRoot = pStack->pTop->nValue->pRight;
223 }
224 }
225 }
226
227 int main(void)
228 {
229 BiTree *pRoot = NULL;
230 RecCreateBiTree(&pRoot);
231 UnRecPrevOrderTraversal(pRoot);
232 printf("\n");
233 UnRecMidOrderTraversal(pRoot);
234 printf("\n");
235 UnRecLastOrderTraversal(pRoot);
236 printf("\n");
237
238 return 0;
239 }
二叉樹的非遞歸遍歷