1 /* *******************************************************************
2 created: 2005/12/30
3 created: 30:12:2005 10:39
4 filename: bintree.h
5 author: Liu Qi
6 purpose: 二叉树的3种遍历方式(包括非递归实现),前序,后序和中序,先访问根节点就是
7 前序(部分书籍称为先根遍历,个人觉得该说法更好^_^),类似的,最后访问根节点就是后序
8 ******************************************************************** */
9
10 #ifndef TREE_H
11 #define TREE_H
12
13 #include < stdio.h >
14 #include < malloc.h >
15 #include < stack >
16 #include < queue >
17 #include < assert.h >
18
19 using namespace std;
20
21 typedef int ElemType;
22 typedef struct treeT
23 {
24 ElemType key;
25 struct treeT * left;
26 struct treeT * right;
27 } treeT, * pTreeT;
28
29 /* ===========================================================================
30 * Function name: visit
31 * Parameter: root:树根节点指针
32 * Precondition:
33 * Description:
34 * Return value:
35 * Author: Liu Qi, //-
36 =========================================================================== */
37 static void visit(pTreeT root)
38 {
39 if (NULL != root)
40 {
41 printf( " %d\n " , root -> key);
42 }
43 }
44
45 /* ===========================================================================
46 * Function name: BT_MakeNode
47 * Parameter: target:元素值
48 * Precondition: None
49 * Postcondition: NULL != pTreeT
50 * Description: 构造一个tree节点,置左右指针为空,并且返回指向新节点的指针
51 * Return value: 指向新节点的指针
52 * Author: Liu Qi, [12/30/2005]
53 =========================================================================== */
54 static pTreeT BT_MakeNode(ElemType target)
55 {
56 pTreeT pNode = (pTreeT) malloc( sizeof (treeT));
57
58 assert( NULL != pNode );
59
60 pNode -> key = target;
61 pNode -> left = NULL;
62 pNode -> right = NULL;
63
64 return pNode;
65 }
66
67
68 /* ===========================================================================
69 * Function name: BT_Insert
70 * Parameter: target:要插入的元素值, pNode:指向某一个节点的指针
71 * Precondition: NULL != ppTree
72 * Description: 插入target到pNode的后面
73 * Return value: 指向新节点的指针
74 * Author: Liu Qi, [12/29/2005]
75 =========================================================================== */
76 pTreeT BT_Insert(ElemType target, pTreeT * ppTree)
77 {
78 pTreeT Node;
79
80 assert( NULL != ppTree );
81
82 Node = * ppTree;
83 if (NULL == Node)
84 {
85 return * ppTree = BT_MakeNode(target);
86 }
87
88 if (Node -> key == target) // 不允许出现相同的元素
89 {
90 return NULL;
91 }
92 else if (Node -> key > target) // 向左
93 {
94 return BT_Insert(target, & Node -> left);
95 }
96 else
97 {
98 return BT_Insert(target, & Node -> right);
99 }
100 }
101
102
103
104
105 /* ===========================================================================
106 * Function name: BT_PreOrder
107 * Parameter: root:树根节点指针
108 * Precondition: None
109 * Description: 前序遍历
110 * Return value: void
111 * Author: Liu Qi, [12/29/2005]
112 =========================================================================== */
113 void BT_PreOrder(pTreeT root)
114 {
115 if (NULL != root)
116 {
117 visit(root);
118 BT_PreOrder(root -> left);
119 BT_PreOrder(root -> right);
120 }
121 }
122
123
124 /* ===========================================================================
125 * Function name: BT_PreOrderNoRec
126 * Parameter: root:树根节点指针
127 * Precondition: Node
128 * Description: 前序(先根)遍历非递归算法
129 * Return value: void
130 * Author: Liu Qi, [1/1/2006]
131 =========================================================================== */
132 void BT_PreOrderNoRec(pTreeT root)
133 {
134 stack < treeT *> s;
135
136 while ((NULL != root) || ! s.empty())
137 {
138 if (NULL != root)
139 {
140 visit(root);
141 s.push(root);
142 root = root -> left;
143 }
144 else
145 {
146 root = s.top();
147 s.pop();
148 root = root -> right;
149 }
150 }
151 }
152
153
154
155 /* ===========================================================================
156 * Function name: BT_InOrder
157 * Parameter: root:树根节点指针
158 * Precondition: None
159 * Description: 中序遍历
160 * Return value: void
161 * Author: Liu Qi, [12/30/2005]
162 =========================================================================== */
163 void BT_InOrder(pTreeT root)
164 {
165 if (NULL != root)
166 {
167 BT_InOrder(root -> left);
168 visit(root);
169 BT_InOrder(root -> right);
170 }
171 }
172
173
174 /* ===========================================================================
175 * Function name: BT_InOrderNoRec
176 * Parameter: root:树根节点指针
177 * Precondition: None
178 * Description: 中序遍历,非递归算法
179 * Return value: void
180 * Author: Liu Qi, [1/1/2006]
181 =========================================================================== */
182 void BT_InOrderNoRec(pTreeT root)
183 {
184 stack < treeT *> s;
185 while ((NULL != root) || ! s.empty())
186 {
187 if (NULL != root)
188 {
189 s.push(root);
190 root = root -> left;
191 }
192 else
193 {
194 root = s.top();
195 visit(root);
196 s.pop();
197 root = root -> right;
198 }
199 }
200 }
201
202
203
204 /* ===========================================================================
205 * Function name: BT_PostOrder
206 * Parameter: root:树根节点指针
207 * Precondition: None
208 * Description: 后序遍历
209 * Return value: void
210 * Author: Liu Qi, [12/30/2005]
211 =========================================================================== */
212 void BT_PostOrder(pTreeT root)
213 {
214 if (NULL != root)
215 {
216 BT_PostOrder(root -> left);
217 BT_PostOrder(root -> right);
218 visit(root);
219 }
220 }
221
222
223 /* ===========================================================================
224 * Function name: BT_PostOrderNoRec
225 * Parameter: root:树根节点指针
226 * Precondition: None
227 * Description: 后序遍历,非递归算法
228 * Return value: void
229 * Author: Liu Qi, // [1/1/2006]
230 =========================================================================== */
231 void BT_PostOrderNoRec(pTreeT root)
232 {
233 // 学习中,尚未明白
234 }
235
236
237 /* ===========================================================================
238 * Function name: BT_LevelOrder
239 * Parameter: root:树根节点指针
240 * Precondition: NULL != root
241 * Description: 层序遍历
242 * Return value: void
243 * Author: Liu Qi, [1/1/2006]
244 =========================================================================== */
245 void BT_LevelOrder(pTreeT root)
246 {
247 queue < treeT *> q;
248 treeT * treePtr;
249
250 assert( NULL != root );
251
252 q.push(root);
253
254 while ( ! q.empty())
255 {
256 treePtr = q.front();
257 q.pop();
258 visit(treePtr);
259
260 if (NULL != treePtr -> left)
261 {
262 q.push(treePtr -> left);
263 }
264 if (NULL != treePtr -> right)
265 {
266 q.push(treePtr -> right);
267 }
268
269 }
270 }
271
272
273 #endif
274
275
276
277
278 测试代码
279
280 #include < stdio.h >
281 #include < stdlib.h >
282 #include < time.h >
283 #include " tree.h "
284
285 #define MAX_CNT 5
286 #define BASE 100
287
288 int main( int argc, char * argv[])
289 {
290 int i;
291 pTreeT root = NULL;
292
293 srand( (unsigned)time( NULL ) );
294
295 for (i = 0 ; i < MAX_CNT; i ++ )
296 {
297 BT_Insert(rand() % BASE, & root);
298 }
299
300 // 前序
301 printf( " PreOrder:\n " );
302 BT_PreOrder(root);
303 printf( " \n " );
304
305 printf( " PreOrder no recursion:\n " );
306 BT_PreOrderNoRec(root);
307 printf( " \n " );
308
309 // 中序
310 printf( " InOrder:\n " );
311 BT_InOrder(root);
312 printf( " \n " );
313
314 printf( " InOrder no recursion:\n " );
315 BT_InOrderNoRec(root);
316 printf( " \n " );
317
318 // 后序
319 printf( " PostOrder:\n " );
320 BT_PostOrder(root);
321 printf( " \n " );
322
323 // 层序
324 printf( " LevelOrder:\n " );
325 BT_LevelOrder(root);
326 printf( " \n " );
327
328 return 0 ;
329 }