二叉树非递归访问,借助一个栈,来模拟递归调用过程。
?
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栈的栈底。
二叉树非递归访问,布布扣,bubuko.com
时间: 2024-12-19 23:41:59