二叉树非递归访问,借助一个栈,来模拟递归调用过程。
1
2
3
4
5
6 |
struct
TreeNode { char
val; TreeNode *left; TreeNode *right; TreeNode( int
x) : val(x), left(NULL), right(NULL) {} }; |
1. 先序遍历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
void
PreOrder(TreeNode *root) { if
(root == NULL) return ; stack<TreeNode*> s; s.push(root); while
(!s.empty()) { TreeNode *node = s.top(); s.pop(); if
(node->right != NULL) s.push(node->right); if
(node ->left != NULL) s.push(node->left); cout << node->val << " " ; } } |
2. 中序遍历
中序遍历,有一个很有意思的规律,从左子树返回,就要访问根节点。
所以,记录一下当前访问状态是下降(访问左子树)状态,还是从左子树返回状态。
从左子树返回后,要访问根节点,同时,如果根节点有右子树,要访问右子树。
右子树访问结束后,整棵访问完的子树又相当于一个左子树。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 |
void
InOrder(TreeNode *root) { if
(root == NULL) return ; stack<TreeNode*> s; s.push(root); TreeNode *prev = NULL; while
(!s.empty()) { TreeNode *curr = s.top(); //当前是下降过程 if
(!prev || prev->left == curr || prev->right == curr) { if
(curr->left != NULL) s.push(curr->left); } else
// 从左子树返回 { s.pop(); cout << curr->val << " " ; if
(curr->right != NULL) s.push(curr->right); } prev = curr; } } |
3. 后序遍历
后序遍历,要在第二次返回的时候访问根节点。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
void
PostOrder(TreeNode *root) { if
(root == NULL) return ; stack<TreeNode*> s; s.push(root); TreeNode *prev = NULL; TreeNode *curr = NULL; while
(!s.empty()) { curr = s.top(); if
(!prev || prev->left == curr || prev->right == curr) { if
(curr->left != NULL) s.push(curr->left); else
if (curr->right != NULL) s.push(curr->right); } else
if (curr->left == prev) //左子树返回 { if
(curr->right != NULL) s.push(curr->right); } else
//从右子树返回 或 无右子树 { s.pop(); cout << curr->val << " " ; } prev = curr; } } |
比较简单的一种后序访问就是采用双栈策略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 |
void
PostOrder(TreeNode *root) { if
(root == NULL) return ; stack<TreeNode*> s; stack<TreeNode*> result; TreeNode *curr = NULL; s.push(root); while
(!s.empty()) { curr = s.top(); s.pop(); result.push(curr); if
(curr->left != NULL) s.push(curr->left); if
(curr->right != NULL) s.push(curr->right); } while
(!result.empty()) { curr = result.top(); result.pop(); cout << curr->val << " " ; } } |
按照后序遍历的顺序,将最后要访问的结点压入result栈的栈底。
原文地址:http://www.cnblogs.com/spch2008/p/3745278.html