二叉搜索树与双向链表

时间:2022-02-26 09:51:29

题目

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


我的思路

一开始并没有理解题目中,不能创建任何新节点的意思,还以为是不能定义任何变量呢,后面看了评论才知道原来是不能使用new来创建节点。总的来说,用中序遍历可以较容易的解决这个问题。


没有定义任何变量版

思路不复杂,只不过在处理上有点繁琐。总的来说就是先递归找到最小的三个节点,然后修改它们之间的左右关系。再返回到上一级,再确定它们之间的左右关系,如此如此这般这般......就可以了。


public TreeNode Convert(TreeNode pRootOfTree) {

    if (pRootOfTree == null) return null;

    if (pRootOfTree.left != null) {
        if (pRootOfTree.left.left == null && pRootOfTree.left.right == null)
            pRootOfTree.left.right = pRootOfTree;
        else {
            Convert(pRootOfTree.left);
            if (pRootOfTree.left.right != null)
                pRootOfTree.left = pRootOfTree.left.right;
            pRootOfTree.left.right = pRootOfTree;
        }
    }
    if (pRootOfTree.right != null) {
        if (pRootOfTree.right.left == null && pRootOfTree.right.right == null)
            pRootOfTree.right.left = pRootOfTree;
        else {
            Convert(pRootOfTree.right);
            if (pRootOfTree.right.left != null)
                pRootOfTree.right = pRootOfTree.right.left;
            pRootOfTree.right.left = pRootOfTree;
        }
    }

    return findLeft(pRootOfTree);
}

//为了找到链表的头结点
private TreeNode findLeft(TreeNode root) {
    while (root.left != null)
        root = root.left;
    return root;
}


中序遍历,简单清晰版

定义两个分别指向链表最左端和最右端的变量(或者说指针)。然后在中序遍历中不断的修改节点之间的指针指向,右指针不断的右移动,直到遍历结束。


private TreeNode leftHead = null;
private TreeNode rightHead = null;

public TreeNode Convert(TreeNode pRootOfTree) {
    if (pRootOfTree == null) return  null;

    Convert(pRootOfTree.left);

    if (leftHead == null) {
        leftHead = pRootOfTree;
        rightHead = pRootOfTree;
    }
    else {
        rightHead.right = pRootOfTree;
        pRootOfTree.left = rightHead;
        rightHead = pRootOfTree;
    }

    Convert(pRootOfTree.right);

    return leftHead;
}