说明:公用代码在上篇数据结构中,以下定义的方法都属于BTreeSort类的成员方法。
先序遍历
1 | // 非递归先序遍历 -- 访问顺序先自己(中间)再左最后右 |
2 | public void preTraversalStack(BTreeNode root) { |
3 | if (null == root) { |
4 | return; |
5 | } |
6 | Stack<BTreeNode> stack = new Stack<BTreeNode>(); |
7 | BTreeNode node = root; |
8 | stack.push(node); |
9 | while (node != null && !stack.isEmpty()) { |
10 | printNode(node); |
11 | // 栈是先进后出所以先把右边入栈 |
12 | if (null !=node.right){ |
13 | stack.add(node.right); |
14 | } |
15 | // 左节点入栈 |
16 | if (null !=node.left){ |
17 | stack.add(node.left); |
18 | } |
19 | node = stack.pop(); |
20 | } |
21 | } |
中序遍历
1 | // 非递归中序遍历 -- 访问顺序先左再自己(中间)最后右 |
2 | public void minTraversalStack(BTreeNode root){ |
3 | if (null == root) { |
4 | return; |
5 | } |
6 | Stack<BTreeNode> stack = new Stack<BTreeNode>(); |
7 | BTreeNode node = root; |
8 | |
9 | while (node != null || !stack.isEmpty()){ |
10 | // 先左 |
11 | while (node != null){ |
12 | stack.push(node); |
13 | node = node.left; |
14 | } |
15 | if (!stack.isEmpty()){ |
16 | node = stack.pop(); |
17 | printNode(node); |
18 | // 控制右转 |
19 | node = node.right; |
20 | } |
21 | } |
22 | } |
后序遍历
1 | // 非递归后序遍历 -- 访问顺序先左再右最后自己(中间) |
2 | public void afterTraversalStack(BTreeNode root){ |
3 | if (null == root) { |
4 | return; |
5 | } |
6 | Stack<BTreeNode> stack = new Stack<BTreeNode>(); |
7 | BTreeNode node = root; |
8 | BTreeNode lastNode = node; // 表示已经被访问过(打印过)的节点 |
9 | while (null != node){ |
10 | // 先左 |
11 | while (node != null){ |
12 | stack.push(node); |
13 | node = node.left; |
14 | } |
15 | node = stack.pop(); |
16 | // 输出访问条件要么节点的右子树为空,要么右子树已经被访问过了 |
17 | while (null == node.right || node.right == lastNode){ |
18 | printNode(node); |
19 | lastNode = node; |
20 | if (stack.isEmpty()){ |
21 | return; |
22 | } |
23 | node = stack.pop(); |
24 | } |
25 | stack.push(node); |
26 | node = node.right; // 右转 |
27 | } |
28 | |
29 | } |
说明:
后序遍历中要注意15行的出栈和25行的入栈,15行的出栈用于判读节点是否满足输出条件,而25行的入栈用于将目前还不满足条件的节点再入栈,随后进行右转。