剑指offer第二版-36.二叉搜索树与双向链表

本系列导航:剑指offer(第二版)java实现导航帖

面试题36:二叉搜索树与双向链表

题目要求:
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,不能创建任何新的节点,只能调整树中节点指针的指向。

解题思路:
二叉树的left、right可以看做双向链表的prev、next,因此可以完成二叉搜索树到双向链表的转换,关键是如何保证转换后为排序好的链表。
最终生成的双向链表有序,而二叉搜索树的中序遍历就是有序的,可按照中序遍历的思路完成此题。关键思路如下:从根节点开始,让左子树部分的最后一节点,中,右子树的第一个节点,这三个节点完成双向链表的重组,然后对于左子树,右子树继续上述重组过程,递归完成。

package chapter4;
import structure.TreeNode;

/**
 * Created by ryder on 2017/7/18.
 * 二叉搜索树与双向链表
 * 将二叉搜索树转换为双向链表,树的left指向prev节点,树的right指向post节点
 * 左右支转换完之后要与根节点组合,所以左右支要返回自己的最小点与最大点两个节点,返回值使用数组
 */
public class P191_ConvertBinarySearchTree {
    public static TreeNode<Integer> convert(TreeNode<Integer> root){
        if(root==null)
            return null;
        TreeNode<Integer>[] result = convertCore(root);
        return result[0];
    }
    public static TreeNode<Integer>[] convertCore(TreeNode<Integer> node){
        //java不支持泛型数组,所以声明为这种形式
        TreeNode[] result = new TreeNode[2];
        if(node.left==null&&node.right==null){
            result[0] = node;
            result[1] = node;
        }
        else if(node.right==null){
            result = convertCore(node.left);
            node.left = result[1];
            result[1].right = node;
            result[1] = node;
        }
        else if(node.left==null){
            result = convertCore(node.right);
            node.right = result[0];
            result[0].left = node;
            result[0] = node;
        }
        else{
            TreeNode[] resultLeft = convertCore(node.left);
            TreeNode[] resultRight = convertCore(node.right);
            resultLeft[1].right = node;
            node.left = resultLeft[1];
            resultRight[0].left = node;
            node.right = resultRight[0];
            result[0] = resultLeft[0];
            result[1] = resultRight[1];
        }
        return result;

    }
    public static void main(String[] args){
        //            10
        //          /   \
        //         6     14
        //       /  \   / \
        //      4    8 12  16
        TreeNode<Integer> root = new TreeNode<Integer>(10);
        root.left = new TreeNode<Integer>(6);
        root.right = new TreeNode<Integer>(14);
        root.left.left = new TreeNode<Integer>(4);
        root.left.right = new TreeNode<Integer>(8);
        root.right.left = new TreeNode<Integer>(12);
        root.right.right = new TreeNode<Integer>(16);
        TreeNode<Integer> result = convert(root);
        //转化后不可再使用二叉树的层序遍历显示结果,层序遍历会进入无限循环。
        System.out.println(result.leftToRight());

    }
}

运行结果

4   6   8   10  12  14  16  

推荐阅读更多精彩内容