Binary Tree Traversal Algorithms (二叉树遍历算法)

本文共列出了11个常见的二叉树遍历算法。二叉树的遍历主要有深度优先遍历和广度优先遍历。深度优先遍历包含前序遍历、中序遍历和后序遍历。

值得一提的是, 其中的 Morris 算法 可以线性时间不需要额外空间(用户栈或系统栈空间)实现二叉树的前序遍历、中序遍历和后序遍历。关于Morris算法, 可参考 http://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html

算法清单:

  A1、 A2、 A3, 分别是中序遍历的递归、迭代、和Morris算法实现。  

  A4、 A5、 A6, 分别是前序遍历的递归、迭代、和Morris算法实现。

  A7、 A8、 A9, 分别是后序遍历的递归、迭代、和Morris算法实现。

  A10 是广度优先遍历算法实现。

  A11 ZigZag顺序的遍历算法。

C++源代码:

  1 #include <iostream>
  2 #include <stack>
  3 #include <queue>
  4 using namespace std;
  5 
  6 struct bt_node {
  7     int value;
  8     bt_node *left, *right;
  9     bt_node(int val = 0) 
 10         : value(val), left(NULL), right(NULL) {} 
 11 };
 12 
 13 void process(bt_node* pnode) {
 14     if (pnode != NULL) 
 15         cout << pnode->value << " ";
 16 }
 17 
 18 // A1
 19 void recursive_inorder_traversal(bt_node* root) {
 20     if (root != NULL) {
 21         recursive_inorder_traversal(root->left);
 22         process(root);
 23         recursive_inorder_traversal(root->right);
 24     }
 25 }
 26 
 27 // A2
 28 void iterative_inorder_traversal(bt_node* root) {
 29     stack<bt_node*> _stack;
 30     bt_node* p = root;
 31     while (p != NULL) {
 32         while (p != NULL) {
 33             _stack.push(p);
 34             p = p->left;
 35         }
 36         p = _stack.top();
 37         _stack.pop();
 38         process(p);
 39         while (p->right == NULL && !_stack.empty()) {
 40             p = _stack.top();
 41             _stack.pop();
 42             process(p);
 43         }
 44         p = p->right;
 45     }
 46 }
 47 
 48 // A3 
 49 void morris_inorder_traversal(bt_node* root) {
 50     bt_node* p = root;
 51     while (p != NULL) {
 52         if (p->left == NULL) {
 53             process(p);
 54             p = p->right;
 55         } else {
 56             bt_node* tmp = p->left;
 57             while (tmp->right != NULL && tmp->right != p) {
 58                 tmp = tmp->right;
 59             }
 60             if (tmp->right == NULL) {
 61                 tmp->right = p;
 62                 p = p->left;
 63             } else {
 64                 tmp->right = NULL;
 65                 process(p);
 66                 p = p->right;
 67             }
 68         }
 69     }
 70 }
 71 
 72 // A4
 73 void recursive_preorder_traversal(bt_node* root) {
 74     if (root != NULL) {
 75         process(root);
 76         recursive_preorder_traversal(root->left);
 77         recursive_preorder_traversal(root->right);
 78     }
 79 }
 80 
 81 // A5
 82 void iterative_preorder_traversal(bt_node* root) {
 83     stack<bt_node*> _stack;
 84     bt_node* p = root;
 85     while (p != NULL) {
 86         while (p != NULL) {
 87             process(p);
 88             _stack.push(p);
 89             p = p->left;
 90         }
 91         p = _stack.top();
 92         _stack.pop();
 93         while (p->right == NULL && !_stack.empty()) {
 94             p = _stack.top();
 95             _stack.pop();
 96         }
 97         p = p->right;
 98     }
 99 }
100 
101 // A6
102 void morris_preorder_traversal(bt_node* root) {
103     bt_node* p = root;
104     while (p != NULL) {
105         if (p->left == NULL) {
106             process(p);
107             p = p->right;
108         } else {
109             bt_node* tmp = p->left;
110             while (tmp->right != NULL && tmp->right != p) 
111                 tmp = tmp->right;
112             if (tmp->right == NULL) {
113                 tmp->right = p;
114                 process(p);
115                 p = p->left;
116             } else {
117                 tmp->right = NULL;
118                 p = p->right;
119             }
120         }
121     }
122 }
123 
124 
125 // A7
126 void recursive_postorder_traversal(bt_node* root) {
127     if (root != NULL) {
128         recursive_postorder_traversal(root->left);
129         recursive_postorder_traversal(root->right);
130         process(root);
131     }
132 }
133 
134 // A8
135 void iterative_postorder_traversal(bt_node* root) {
136     stack<bt_node*> _stack;
137     bt_node *p = root, *q = NULL;
138     while (p != NULL) {
139         _stack.push(p);
140         p = p->left;
141     }
142     while (!_stack.empty()) {
143         p = _stack.top();
144         if (p->right == NULL || p->right == q) {
145             _stack.pop();
146             process(p);
147             q = p;
148         } else {
149             p = p->right;
150             while (p != NULL) {
151                 _stack.push(p);
152                 p = p->left;
153             }
154         }
155     }
156 }
157 
158 bt_node* reverse(bt_node* pnode) {
159     bt_node aux_node;
160     bt_node* p = &aux_node;
161     bt_node* q = pnode;
162     while (q != NULL) {
163         bt_node* next = q->right;
164         q->right = p->right;
165         p->right = q;
166         q = next;
167     }
168     return p->right;
169 }
170 
171 void process_in_reverse_order(bt_node* pnode) {
172     pnode = reverse(pnode);
173     bt_node* p = pnode;
174     while (p != NULL) {
175         process(p);
176         p = p->right;
177     }
178     reverse(pnode);
179 }
180 
181 // A9
182 void morris_postorder_traversal(bt_node* root) {
183     bt_node dummy;
184     dummy.left = root;
185     bt_node *p = &dummy;
186     while (p != NULL) {
187         if (p->left == NULL) {
188             p = p->right;
189         } else {
190             bt_node* tmp = p->left;
191             while (tmp->right != NULL && tmp->right != p) 
192                 tmp = tmp->right;
193             if (tmp->right == NULL) {
194                 tmp->right = p;
195                 p = p->left;
196             } else {
197                 tmp->right = NULL;
198                 process_in_reverse_order(p->left);
199                 p = p->right;
200             }
201         }
202     }
203 }
204 
205 // A10
206 void breadth_first_traversal(bt_node* root) {
207     queue<bt_node*> _queue;
208     _queue.push(root);
209     while (!_queue.empty()) {
210         bt_node* p = _queue.front();
211         _queue.pop();
212         process(p);
213         if (p->left != NULL) {
214             _queue.push(p->left);
215         } 
216         if (p->right != NULL) {
217             _queue.push(p->right);
218         }
219     }
220 }
221 
222 // A11
223 void zigzag_order_traversal(bt_node* root) {
224     stack<bt_node*> _stack1;
225     stack<bt_node*> _stack2;
226     _stack1.push(root);
227     int left_first = 1;
228     while (!_stack1.empty()) {
229         while (!_stack1.empty()) {
230             bt_node* p = _stack1.top();
231             _stack1.pop();
232             process(p);
233             if (left_first) {
234                 if (p->left != NULL)
235                     _stack2.push(p->left);
236                 if (p->right != NULL) 
237                     _stack2.push(p->right);
238             } else {
239                 if (p->right != NULL)
240                     _stack2.push(p->right);
241                 if (p->left != NULL)
242                     _stack2.push(p->left);
243             }
244         }
245         left_first = left_first ^ 0x01;
246         _stack1.swap(_stack2); // C++11 Standard
247     }
248 }
249 
250 // Test
251 int main() {
252     const int n = 7;
253     bt_node* ptr[n];
254     for (int i = 0; i < n; i++) {
255         ptr[i] = new bt_node(i+1);
256     }
257     ptr[0]->left = ptr[1];
258     ptr[0]->right = ptr[2];
259     ptr[1]->left = ptr[3];
260     ptr[1]->right = ptr[4];
261     ptr[2]->left = ptr[5];
262     ptr[4]->left = ptr[6];
263 
264     /*
265      *             1
266      *           /   
267      *          2     3
268      *         /    /
269      *        4   5 6 
270      *           /
271      *          7
272      */
273 
274     recursive_inorder_traversal(ptr[0]);
275     cout << endl;
276     iterative_inorder_traversal(ptr[0]);
277     cout << endl;
278     morris_inorder_traversal(ptr[0]);
279     cout << endl;
280 
281     recursive_preorder_traversal(ptr[0]);
282     cout << endl;
283     iterative_preorder_traversal(ptr[0]);
284     cout << endl;
285     morris_preorder_traversal(ptr[0]);
286     cout << endl;
287 
288     recursive_postorder_traversal(ptr[0]);
289     cout << endl;
290     iterative_postorder_traversal(ptr[0]);
291     cout << endl;
292     morris_postorder_traversal(ptr[0]);
293     cout << endl;
294 
295     breadth_first_traversal(ptr[0]);
296     cout << endl;
297     zigzag_order_traversal(ptr[0]);
298     cout << endl;
299 
300     for (int i = 0; i < n; i++) {
301         delete ptr[i];
302     }
303     return 0;
304 }

程序输出:

4 2 7 5 1 6 3 
4 2 7 5 1 6 3 
4 2 7 5 1 6 3 
1 2 4 5 7 3 6 
1 2 4 5 7 3 6 
1 2 4 5 7 3 6 
4 7 5 2 6 3 1 
4 7 5 2 6 3 1 
4 7 5 2 6 3 1 
1 2 3 4 5 6 7 
1 3 2 4 5 6 7
原文地址:https://www.cnblogs.com/william-cheung/p/4623792.html