【题目】根据二叉树的前序和中序遍历,重建二叉树,返回根节点。
1. 根据前序遍历,找到根节点。
2. 在中序遍历中找到根节点的位置,进而得到中序遍历中左右两个子树的划分位置。
3. 在前序遍历中找到左右两个子树的位置。
4. 根据这些位置,对左右子树分别进行递归操作,得到根节点的左右孩子节点。
1 public class Main { 2 3 public static void main(String[] args) throws Exception { 4 5 int[] pre = { 1, 2, 4, 7, 3, 5, 6, 8 }; 6 int[] mid = { 4, 7, 2, 1, 5, 3, 8, 6 }; 7 8 Main main = new Main(); 9 Node root = main.process(pre, mid, 8); 10 11 // 验证:前序遍历 12 main.pre(root); 13 14 System.out.println(); 15 16 // 验证:中序遍历 17 main.mid(root); 18 19 System.out.println(); 20 21 // 验证:后序遍历 22 main.back(root); 23 } 24 25 public Node process(int[] pre, int[] mid, int length) throws Exception { 26 27 if (null == pre || null == mid || length <= 0) { 28 return null; 29 } 30 31 return buildTree(0, pre.length - 1, 0, mid.length - 1, pre, mid); 32 } 33 34 public Node buildTree(int startPre, int endPre, int startMid, int endMid, 35 int[] pre, int[] mid) throws Exception { 36 37 // 得到前序遍历第一个节点--根节点 38 int rootValue = pre[startPre]; 39 Node rootNode = new Node(rootValue, null, null); 40 41 if (startPre == endPre) { 42 if (startMid == endMid && pre[startPre] == mid[startMid]) { 43 return rootNode; 44 } else { 45 throw new Exception("invalid input"); 46 } 47 } 48 49 // 在中序遍历中找到根节点的位置 50 int rootIndex = startMid; 51 while (rootIndex <= endMid && mid[rootIndex] != rootValue) { 52 rootIndex++; 53 } 54 if (rootIndex == endMid && mid[rootIndex] != rootValue) { 55 throw new Exception("invalid input"); 56 } 57 58 int leftLength = rootIndex - startMid; 59 int preLeftEnd = startPre + leftLength; 60 61 // 递归构建左子树 62 if (leftLength > 0) { 63 rootNode.setLeft(buildTree(startPre + 1, preLeftEnd, startMid, 64 rootIndex - 1, pre, mid)); 65 } 66 67 // 递归构建右子树 68 if (leftLength < endPre - startPre) { 69 rootNode.setRight(buildTree(preLeftEnd + 1, endPre, rootIndex + 1, 70 endMid, pre, mid)); 71 } 72 73 return rootNode; 74 } 75 76 public void pre(Node root) { 77 78 if (null != root) { 79 System.out.print(root.getValue() + " "); 80 } 81 82 if (null != root.getLeft()) { 83 pre(root.getLeft()); 84 } 85 86 if (null != root.getRight()) { 87 pre(root.getRight()); 88 } 89 } 90 91 public void mid(Node root) { 92 93 if (null != root.getLeft()) { 94 mid(root.getLeft()); 95 } 96 97 if (null != root) { 98 System.out.print(root.getValue() + " "); 99 } 100 101 if (null != root.getRight()) { 102 mid(root.getRight()); 103 } 104 } 105 106 public void back(Node root) { 107 108 if (null != root.getLeft()) { 109 back(root.getLeft()); 110 } 111 112 if (null != root.getRight()) { 113 back(root.getRight()); 114 } 115 116 if (null != root) { 117 System.out.print(root.getValue() + " "); 118 } 119 } 120 } 121 122 class Node { 123 private int value; 124 private Node left; 125 private Node right; 126 127 public Node(int value, Node left, Node right) { 128 this.value = value; 129 this.left = left; 130 this.right = right; 131 } 132 133 public int getValue() { 134 return value; 135 } 136 137 public void setLeft(Node left) { 138 this.left = left; 139 } 140 141 public Node getLeft() { 142 return left; 143 } 144 145 public void setRight(Node right) { 146 this.right = right; 147 } 148 149 public Node getRight() { 150 return right; 151 } 152 153 }