很简单,知道一棵二叉树的前序和中序,要求重建此二叉树。
由前序可知道根结点的值,然后遍历中序,可以找到根结点的位置,然后在该位置的左边就是根结点的左子树,右边就是右子树,然后通过递归就可以得到整棵树。
/** * decription: 树节点 * @author : linjq */ private class TreeNode { private int element; private TreeNode left; private TreeNode right; public TreeNode(int element) { this.element = element; } }
/** * decription: 重构二叉树,知道前序和中序 解决思路:由前序可知道一个树结点的值,然后在中序那里找到那个值,记录位置,它左边的是它的 * 左子树,右边是右子树,依次递归可得到整棵树。 * @author : linjq */ private TreeNode rebuidTree(int[] preOrder, int[] inOrder, int preBegin, int preEnd, int inBegin, int inEnd) { if (preBegin > preEnd || inBegin > inEnd) { return null; // 证明已到尽头,返回空结点 } else { TreeNode rootNode = new TreeNode(preOrder[preBegin]); // 当前节点值在中序的位置,找到该位置是为了找到这个结点的左右子树 int rootInPosition = -1; for (int i = inBegin; i <= inEnd; i++) { if (inOrder[i] == rootNode.element) { rootInPosition = i; break; } } //下面是准确定位到哪些是它的左子树范围,哪些事右子树 int leftNum = rootInPosition - inBegin;// 左子树 有多少个结点 int leftPreBegin = preBegin + 1; int leftPreEnd = preBegin + leftNum; int leftInBegin = inBegin; int leftInEnd = inBegin + leftNum; int rightPreBegin = preBegin + 1 + leftNum; int rightPreEnd = preEnd; int rightInBegin = rootInPosition + 1; int rightInEnd = inEnd; // 寻找该结点的左子树,右子树 TreeNode leftNode = rebuidTree(preOrder, inOrder, leftPreBegin, leftPreEnd, leftInBegin, leftInEnd); TreeNode righNode = rebuidTree(preOrder, inOrder, rightPreBegin, rightPreEnd, rightInBegin, rightInEnd); rootNode.left = leftNode; rootNode.right = righNode; return rootNode; } } /** * decription:中序遍历 * @author : linjq */ public void inOrder(TreeNode rootNode) { if (rootNode == null) { return; } else { inOrder(rootNode.left); System.out.print(rootNode.element + " "); inOrder(rootNode.right); } } /** * decription:前序遍历 * @author : linjq */ public void preOrder(TreeNode rootNode) { if (rootNode == null) { return; } else { System.out.print(rootNode.element + " "); preOrder(rootNode.left); preOrder(rootNode.right); } }
/** * decription: main方法 测试 重建二叉树 * @author : linjq */ public static void main(String[] args) { RecoverBST bst = new RecoverBST(); int[] inOrder = {4,7,2,1,5,3,8,6}; int[] preOrder = {1,2,4,7,3,5,6,8}; TreeNode root = bst.rebuidTree(preOrder, inOrder, 0, preOrder.length-1, 0, inOrder.length-1); System.out.println("重建后的中序"); //输出中序 bst.inOrder(root); System.out.println(); System.out.println("重建后的前序"); //输出前序 bst.preOrder(root); }
对比给定的已知条件,它们一致,代码正确。然而,递归的方法虽然简单,当该二叉树很深很深,比如深度达到1000以上的时候,用递归就不好了,容易造成栈溢出。因此,换成非递归方法来实现是更好的选择。
原文地址:http://blog.csdn.net/linfeng24/article/details/39051151