算法Java实现对二叉树前序/中序/后序的递归与非递归算法
代长亚二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
首先创建节点类,并在里面添加了一个创建树的方法,调用后就可以返回一个包含7个节点的二叉树。
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 35 36 37 38 39 40 41 42 43 44 45
| public class Node { // 节点值 public int value;
// 左子节点 public Node left;
// 右子节点 public Node right;
Node(int va) { value = va; }
Node(int va, Node le, Node ri) { value = va; left = le; ri = right; }
/** * 创建一颗二叉树 * * @return 根节点 */ public static Node createTree() { Node root = new Node(0); Node node1 = new Node(1); Node node2 = new Node(2); Node node3 = new Node(3); Node node4 = new Node(4); Node node5 = new Node(5); Node node6 = new Node(6); Node node7 = new Node(7);
root.left = node1; root.right = node2; node1.left = node3; node1.right = node4; node2.left = node5; node2.right = node6; node3.left = node7; return root; } }
|
创建遍历类,在该类里实现各种遍历方法。
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
| import java.util.ArrayList;
public class Traverse {
/** * 递归前序遍历 * * @param root */ public void recursiveProOrder(Node root) { // 遍历根节点 if (root != null) { System.out.print(root.value); } // 遍历左子树 if (root.left != null) { recursiveProOrder(root.left); } // 遍历右子树 if (root.right != null) { recursiveProOrder(root.right); } }
/** * 前序遍历 * * @param root */ public void proOrder(Node root) { // 使用ArrayList作为堆栈 ArrayList<Node> stack = new ArrayList<Node>(); // 栈指针 int top = -1; Node current = root; while (true) { if (current != null) { System.out.print(current.value); } // 右子节点进栈 if (current.right != null) { stack.add(current.right); top++; } // 左子节点进栈 if (current.left != null) { stack.add(current.left); top++; } // 如果栈内还有节点,栈顶节点出栈 if (top > -1) { current = stack.get(top); stack.remove(top--); } else { break; } } }
/** * 递归中序遍历 * * @param root */ public void recursiveInOrder(Node root) { if (root != null) { if (root.left != null) { recursiveInOrder(root.left); } System.out.print(root.value); if (root.right != null) { recursiveInOrder(root.right); } } }
/** * 中序遍历 * * @param root */ public void inOrder(Node root) { if (root != null) { ArrayList<Node> stack = new ArrayList<Node>(); int top = -1; Node current = root; while (current != null || top > -1) { if (current != null) { // 一直深入地寻找左子节点,并将路上的节点都进栈 stack.add(current); top++; current = current.left; } else { // 取出栈顶节点,并继续遍历右子树 current = stack.get(top); stack.remove(top--); System.out.print(current.value); current = current.right; } } } }
/** * 递归后续遍历 * * @param root */ public void recursivePostOrder(Node root) { if (root != null) { if (root.left != null) { recursivePostOrder(root.left); } if (root.right != null) { recursivePostOrder(root.right); } System.out.print(root.value); } }
/** * 后序遍历:可以被遍历的节点都要进栈出栈两次,所以添加第二个栈用来标示进栈次数 * * @param root */ public void postOrder(Node root) { if (root != null) { // 用来保存节点的栈 ArrayList<Node> stack = new ArrayList<Node>(); // 用来保存标志位的栈 ArrayList<Integer> stack2 = new ArrayList<Integer>(); // 两个栈共用的栈指针 int top = -1; int tag; Node current = root; do { //将所有左子节点进栈 while (current != null) { stack.add(current); stack2.add(0); top++; current = current.left; } //取出栈顶节点,并判断其标志位 current = stack.get(top); tag = stack2.get(top); stack2.remove(top); if (tag == 0) { // tag为0,表明该节点第一次进栈,还需要进栈一次,同时修改标志位 current = current.right; stack2.add(1); } else { // tag不位0,表明非首次进栈,可以遍历了。 stack.remove(top); top--; System.out.print(current.value); current = null; } } while (current != null || top != -1); } } }
|
实例化遍历类并调用各个遍历方法。
点击(此处)折叠或打开
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Algorithm {
public static void main(String[] args) {
Node root=Node.createTree(); System.out.print("前序遍历: "); new Traverse().proOrder(root); System.out.println(); System.out.print("前序递归遍历: "); new Traverse().recursiveProOrder(root); System.out.println(); System.out.print("中序遍历: "); new Traverse().inOrder(root); System.out.println(); System.out.print("中序递归遍历: "); new Traverse().recursiveInOrder(root); System.out.println(); System.out.print("后序遍历: "); new Traverse().postOrder(root); System.out.println(); System.out.print("后序递归遍历: "); new Traverse().recursivePostOrder(root); }
|
输出结果:
前序遍历: 01374256
前序递归遍历: 01374256
中序遍历: 73140526
中序递归遍历: 73140526
后序遍历: 73415620
后序递归遍历: 73415620