二叉树非递归遍历

二叉树非递归遍历,可以采用堆栈实现,也可以采用非堆栈用指针实现。感觉堆栈实现很像递归实现,只是要自己把节点压入堆栈,弹出堆栈。非堆栈实现也有两种方法,可以在节点结构中添加标志位以显示当前节点是否已经被遍历过,也可以不用标志位,只用指针表示。这里实现了采用堆栈方式和非堆栈非标志位两种方法。

View Code
  1 #include <iostream>
  2 #include <stack>
  3 #include <ctime>
  4 #include <random>
  5 
  6 using namespace std;
  7 
  8 template<class T>
  9 struct tree_node
 10 {
 11     T data;
 12     tree_node<T> *l_child;
 13     tree_node<T> *r_child;
 14     tree_node<T> *parent;
 15 };
 16 
 17 /**********************************************************************************
 18 Function:       // pre_order_stack
 19 Description:    // 二叉树非递归前序遍历,采用堆栈方法
 20 Input:          // root: 树节点指针
 21 Return:         // 无
 22 **********************************************************************************/
 23 template<class T>
 24 void pre_order_stack(tree_node<T> *root)
 25 {
 26     stack<tree_node<T> *> node_stack;
 27     tree_node<T> *node = root;
 28     while(NULL != node || !node_stack.empty())
 29     {
 30         if (NULL != node)
 31         {
 32             cout << node->data << " ";
 33             node_stack.push(node);
 34             node = node->l_child;
 35         }
 36         else
 37         {
 38             node = node_stack.top();
 39             node_stack.pop();
 40             node = node->r_child;
 41         }
 42     }
 43     cout << endl;
 44 }
 45 
 46 /**********************************************************************************
 47 Function:       // pre_order_no_stack
 48 Description:    // 二叉树非递归前序遍历,非堆栈实现,主要通过两个子节点标志来判断
 49                 // 当前节点是否已经遍历过了
 50 Input:          // root: 二叉树节点指针
 51 Return:         // 无
 52 **********************************************************************************/
 53 template<class T>
 54 void pre_order_no_stack(tree_node<T> *root)
 55 {
 56     tree_node<T> *temp = root;
 57     //左子节点标志
 58     tree_node<T> *tmpl = NULL;
 59     //右子结点标志
 60     tree_node<T> *tmpr = NULL;
 61     while(NULL != temp)
 62     {    
 63         //当前节点没有遍历过,则输出节点数据
 64         if ((NULL != temp->l_child && temp->l_child == tmpl) 
 65              || (NULL != temp->r_child && temp->r_child == tmpr))
 66         {
 67         }
 68         else
 69         {
 70             cout << temp->data << " ";
 71         }
 72         //遍历左子树
 73         if(NULL != temp->l_child && tmpl != temp->l_child)
 74         {
 75             temp = temp->l_child;
 76         }
 77         //遍历右子树
 78         else if (NULL != temp->r_child && tmpr != temp->r_child)
 79         {
 80             temp = temp->r_child;
 81         }
 82         //回溯
 83         else if(NULL != temp->parent)
 84         {
 85             //修改节点标志指针
 86             if (temp->parent->l_child == temp)
 87             {
 88                 tmpl = temp;
 89             }
 90             if(temp->parent->r_child == temp)
 91             {
 92                 tmpr = temp;
 93                 tmpl = temp->parent->l_child;
 94             }
 95             temp = temp->parent;
 96         }
 97         else
 98         {
 99             break;
100         }
101     }
102     cout << endl;
103 }
104 
105 /**********************************************************************************
106 Function:       // in_order_stack
107 Description:    // 二叉树中序遍历堆栈实现版本
108 Input:          // root: 二叉树节点
109 Return:         // 无
110 **********************************************************************************/
111 template<class T>
112 void in_order_stack(tree_node<T> *root)
113 {
114     stack<tree_node<T>* > node_stack;
115     tree_node<T> *temp = root;
116     while(NULL != temp || !node_stack.empty())
117     {
118         if(NULL != temp)
119         {
120             node_stack.push(temp);
121             temp = temp->l_child;
122         }
123         else
124         {
125             temp = node_stack.top();
126             cout << temp->data << " ";
127             node_stack.pop();
128             temp = temp->r_child;
129         }
130     }
131     cout << endl;
132 }
133 
134 /**********************************************************************************
135 Function:       // in_order_no_stack
136 Description:    // 二叉树非递归非堆栈中序遍历
137 Input:          // root: 二叉树节点指针
138 Return:         // 无
139 **********************************************************************************/
140 template<class T>
141 void in_order_no_stack(tree_node<T> *root)
142 {
143     tree_node<T> *temp = root;
144     //左子节点标志
145     tree_node<T> *tmpl = NULL;
146     //右子结点标志
147     tree_node<T> *tmpr = NULL;
148     while (NULL != temp)
149     {
150         //遍历左子树
151         if (NULL != temp->l_child && temp->l_child != tmpl)
152         {
153             temp = temp->l_child;
154         }
155         else
156         {
157             //当前节点没有遍历过,则输出节点数据,中序遍历要先遍历左子树之后才能遍历当前节点
158             if (temp->l_child == tmpl && !(NULL != tmpr && temp->r_child == tmpr))
159             {
160                 cout << temp->data << " ";
161             }
162             //遍历右子树            
163             if(NULL != temp->r_child && temp->r_child != tmpr)
164             {
165                 temp = temp->r_child;
166                 tmpl = NULL;
167             }
168             else
169             {
170                 //修改节点标志指针
171                 if(NULL != temp->parent)
172                 {
173                     if (temp == temp->parent->l_child)
174                     {
175                         tmpl = temp;
176                     }
177                     else
178                     {
179                         tmpr = temp;
180                         tmpl = temp->parent->l_child;
181                     }
182                     temp = temp->parent;
183                 }
184                 else
185                 {
186                     break;
187                 }
188             }
189         }
190     }
191     cout << endl;
192 }
193 
194 /**********************************************************************************
195 Function:       // post_order_stack
196 Description:    // 二叉树非递归后序遍历堆栈实现版
197 Input:          // root: 二叉树节点
198 Return:         // 无
199 **********************************************************************************/
200 template<class T>
201 void post_order_stack(tree_node<T> *root)
202 {
203     if (NULL == root)
204     {
205         return;
206     }
207     stack<tree_node<T>*> node_stack;
208     tree_node<T> *temp = root;
209     tree_node<T> *tmpl  = NULL;
210     tree_node<T> *tmpr = NULL;
211     while(NULL != temp || !node_stack.empty())
212     {
213         if(NULL != temp->l_child && tmpl != temp->l_child)
214         {
215             node_stack.push(temp);
216             temp = temp->l_child;
217         }
218         else if (NULL != temp->r_child && tmpr != temp->r_child)
219         {
220             node_stack.push(temp);
221             temp = temp->r_child;
222         }
223         else
224         {
225             cout << temp->data << " ";
226             if(!node_stack.empty())
227             {
228                 if(temp == node_stack.top()->l_child)
229                 {
230                     tmpl = temp;
231                 }
232                 else
233                 {
234                     tmpr = temp;
235                     tmpl = temp->parent->l_child;
236                 }
237                 temp = node_stack.top();
238                 node_stack.pop();
239                 if (temp == root && tmpr == temp->r_child)
240                 {
241                     cout << temp->data << " ";
242                     break;
243                 }
244             }
245             else
246             {
247                 break;
248             }
249         }
250     }
251     cout << endl;
252 }
253 

254 /**********************************************************************************
255 Function:       // post_order_stack
256 Description:    // 二叉树非递归后序遍历非堆栈实现版
257 Input:          // root: 二叉树节点
258 Return:         // 无
259 **********************************************************************************/
260 template<class T>
261 void post_order_no_stack(tree_node<T> *root)
262 {
263     tree_node<T> *temp = root;
264     tree_node<T> *tmpl = NULL;
265     tree_node<T> *tmpr = NULL;
266     while(NULL != temp)
267     {
268         if(temp->l_child != NULL && tmpl != temp->l_child)
269         {
270             temp = temp->l_child;
271             tmpl = NULL;
272             tmpr = NULL;
273         }
274         else if(NULL != temp->r_child && tmpr != temp->r_child)
275         {
276             temp = temp->r_child;
277             tmpl = NULL;
278             tmpr = NULL;
279         }
280         else
281         {
282             if(temp->l_child == tmpl && temp->r_child == tmpr)
283             {
284                 cout << temp->data << " ";
285             }
286             if(NULL != temp->parent)
287             {
288                 if(temp == temp->parent->l_child)
289                 {
290                     tmpl = temp;
291                     tmpr = NULL;
292                 }
293                 else
294                 {
295                     tmpr = temp;
296                     tmpl = temp->parent->l_child;
297                 }
298                 temp = temp->parent;
299             }
300             else
301             {
302                 break;
303             }
304         }
305     }
306 }
307 
308 /**********************************************************************************
309 Function:       // insert_node
310 Description:    // 输出数组的最小前n个数
311 Input:          // root: 二叉树节点
312                 // data:    节点中的数据
313 Return:         // 无
314 **********************************************************************************/
315 template<class T>
316 void insert_node(tree_node<T> *&root, T data)
317 {
318     tree_node<T> *new_node = new tree_node<T>;
319     new_node->data = data;
320     new_node->l_child = NULL;
321     new_node->parent = NULL;
322     new_node->r_child = NULL;
323     if (root == NULL)
324     {
325         root = new_node;    
326     }
327     else
328     {
329         tree_node<T> *temp = root;
330         tree_node<T> *tmp;
331         while(NULL != temp)
332         {
333             tmp = temp;
334             if(data > temp->data)
335             {
336                 temp = temp->r_child;
337             }
338             else
339             {
340                 temp = temp->l_child;
341             }
342         }
343         if (data > tmp->data)
344         {
345             tmp->r_child = new_node;
346         }
347         else
348         {
349             tmp->l_child = new_node;
350         }
351         new_node->parent = tmp;
352     }
353 }
354 
355 /**********************************************************************************
356 Function:       // delete_tree
357 Description:    // 删除整个树
358 Input:          // root: 二叉树节点
359 Return:         // 无
360 **********************************************************************************/
361 template<class T>
362 void delete_tree(tree_node<T> *root)
363 {
364     if(NULL != root)
365     {
366         delete_tree(root->l_child);
367         delete_tree(root->r_child);
368         delete root;
369     }
370 }
371     
372 
373 int main()
374 {
375     tree_node<int> *root = NULL;
376     srand(time(0));
377     for(int i = 0; i < 10; ++i)
378     {
379         insert_node(root, rand() % 20);
380     }
381     //insert_node(root, 6);
382     //insert_node(root, 9);
383     //insert_node(root, 11);
384     //insert_node(root, 4);
385     //insert_node(root, 8);
386     //insert_node(root, 3);
387     //insert_node(root, 5);
388     pre_order_stack(root);
389     pre_order_no_stack(root);
390     in_order_stack(root);
391     in_order_no_stack(root);
392     post_order_stack(root);
393     post_order_no_stack(root);
394     delete_tree(root);
395     return 0;
396 }

 

posted on 2013-04-24 15:14  blue firmament  阅读(190)  评论(0编辑  收藏  举报