说明:公用代码在上篇数据结构中,以下定义的方法都属于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行的入栈用于将目前还不满足条件的节点再入栈,随后进行右转。