二叉树遍历方式的转换

Posted by Elijah's Blog on Tuesday, March 21, 2017

在学习树的时候,碰到了一道题,是如何从先序遍历和中序遍历的结果中得到后序遍历,正常情况下第一反应就是重建二叉树,然后再后序输出,在室友的指点下发现可以通过对数组的操作得到结果,重点是如何把握好指向节点的位置

从先序或者后序结合中序得到后续或者先序或者层次序列比较容易,但是对于先序结合后序得到中序是有一定困难的,因为可能得到的树不是唯一的,所以在这里就不讨论这种情况

假设我们有一棵二叉树,各种遍历方式输出结果如下表所示

遍历\节点012345
先序遍历123456
中序遍历324165
后序遍历342651
层次遍历125346
    /**
     * 从先序中序获取后序
     * @param preorder 先序序列
     * @param inorder 中序序列
     * @param root 根节点  初始值为0
     * @param start 起始节点  初始值为0
     * @param end 终止节点  初始值为preorder.length - 1
     */
    public void PostorderFromPreorderInorder(int[] preorder, int[] inorder, int root, int start, int end) {
        if (start > end) return;
        int i = start;
        while (i < end && inorder[i] != preorder[root]) i++;  //让i指向中序遍历的根节点
        PostorderFromPreorderInorder(preorder, inorder, root + 1, start, i - 1);    //遍历左子树
        PostorderFromPreorderInorder(preorder, inorder, root + i + 1 - start, i + 1, end);  //遍历右子树
        System.out.print(preorder[root] + " ");
    }
    /**
     * 从中序后序获取先序
     * @param inorder 中序序列
     * @param postorder 后序序列
     * @param root 根节点  初始值为postorder.length - 1
     * @param start 起始节点  初始值为0
     * @param end 终止节点  初始值为postorder.length - 1
     */
    public void PreorderFromInorderPostorder(int[] inorder, int[] postorder, int root, int start, int end) {
        if (start > end) return;
        int i = start;
        while (i < end && inorder[i] != postorder[root]) i++;  //让i指向中序遍历的根节点
        System.out.print(postorder[root] + " ");
        PreorderFromInorderPostorder(inorder, postorder, root - 1 - end + i, start, i - 1); //遍历左子树
        PreorderFromInorderPostorder(inorder, postorder, root - 1, i + 1, end);     //遍历右子树
    }
    /**
     * 从前序中序获取层次
     * @param preorder 前序序列
     * @param inorder 中序序列
     * @param levelorder 存储层次序列结果
     * @param root 根节点  初始值为preorder.length - 1
     * @param start 起始节点  初始值为0
     * @param end 终止节点  初始值为preorder.length - 1
     * @param index 层次序列的指针  初始值为0
     */
    public void LavelorderFromPreorderInorder(int[] preorder, int[] inorder, int[] levelorder, int root, int start, int end, int index) {
        if (start > end) return;
        int i = start;
        while (i < end && inorder[i] != preorder[root]) i++;
        levelorder[index] = preorder[root];
        LavelorderFromPreorderInorder(preorder, inorder, levelorder, root + 1, start, i - 1, 2 * index + 1);
        LavelorderFromPreorderInorder(preorder, inorder, levelorder, root + i + 1 - start, i + 1, end, 2 * index + 2);
    }
    /**
     * 从中序后序获取层次
     * @param inorder 中序序列
     * @param postorder 后序序列
     * @param levelorder 存储层次序列结果
     * @param root 根节点  初始值为0
     * @param start 起始节点  初始值为0
     * @param end 终止节点  初始值为postorder.length - 1
     * @param index 层次序列的指针  初始值为0
     */
    public void LavelorderFromInorderPostorder(int[] inorder, int[] postorder, int[] levelorder, int root, int start, int end, int index) {
        if (start > end) return;
        int i = start;
        while (i < end && inorder[i] != postorder[root]) i++;
        levelorder[index] = postorder[root];
        LavelorderFromInorderPostorder(inorder, postorder, levelorder, root - 1 - end + i, start, i - 1, 2 * index + 1);
        LavelorderFromInorderPostorder(inorder, postorder, levelorder, root - 1, i + 1, end, 2 * index + 2);
    }