输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如,输入前序遍历序列{1,2,4,7,3,5,6,8},中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
1 namespace JianZhiOffer 2 { 3 public class TreeNode 4 { 5 public int val; 6 public TreeNode left; 7 public TreeNode right; 8 9 public TreeNode(int x) 10 { 11 val = x; 12 } 13 } 14 15 class ReBuiltBinaryTree 16 { 17 public TreeNode reConstructBinaryTree(int[] pre, int[] tin) 18 { 19 // write code here 20 if (pre == null || tin == null) 21 { 22 return null; 23 } 24 25 return reCBT(pre, 0, pre.Length - 1, tin, 0, tin.Length - 1); 26 } 27 28 /// <summary> 29 /// 利用递归分别处理左右子树 30 /// </summary> 31 /// <param name="pre">前序序列</param> 32 /// <param name="headPre">前序序列首元素</param> 33 /// <param name="tailPre">前序序列尾元素</param> 34 /// <param name="tin">中序序列</param> 35 /// <param name="headTin">中序序列首元素</param> 36 /// <param name="tailTin">中序序列尾元素</param> 37 /// <returns></returns> 38 public TreeNode reCBT(int[] pre, int headPre, int tailPre, int[] tin, int headTin, int tailTin) 39 { 40 if (headPre > tailPre || headTin > tailTin) 41 { 42 return null; 43 } 44 45 // 前序序列的首元素为二叉树的根结点 46 TreeNode rootNode = new TreeNode(pre[headPre]); 47 48 // 遍历中序序列, 如果遇到和根结点相等的元素, 则前面的元素为左子树的结点, 后面的元素为右子树的结点 49 // 左子树元素个数:i - headTin + 1 50 // 前序序列中, 左子树首元素:headPre + 1, 左子树尾元素:headPre + 1 + (i - headTin - 1) 51 // 右子树元素个数:tailTin - i + 1 52 // 前序序列中, 右子树首元素:headPre + (i - headTin + 1), 右子树尾元素:tailPre 53 for (int i = headTin; i <= tailTin; i++) 54 { 55 if (rootNode.val == tin[i]) 56 { 57 rootNode.left = reCBT(pre, headPre + 1, headPre + (i - headTin), tin, headTin, i - 1); 58 rootNode.right = reCBT(pre, headPre + (i - headTin) + 1, tailPre, tin, i + 1, tailTin); 59 } 60 } 61 62 return rootNode; 63 } 64 } 65 }