JAVA: 二叉搜索树与双向链表

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

解法一:递归算法

    1、将左子树构成双链表,并返回该链表的头节点(左子树最左边的节点)
    2、定位到左链表的最后一个节点(左子树最右边的节点)
    3、如果左子树链表不为空,则将当前root追加到左子树链表后
    4、将右子树构造成双向链表,并返回链表头结点(右子树最左边的节点)
    5、如果右子树链表不为空,将右子树链表追加到当前root后
    6、根据左子树链表是否为空返回的整体双向链表的头节点

//Convert函数把一个二叉搜索树变成一个有序的双向链表,返回双向链表的头结点,参数root为二叉搜索树的根节点
    public TreeNode Convert1(TreeNode pRootOfTree) {
        if(pRootOfTree==null)  return null;
        if(pRootOfTree.left==null && pRootOfTree.right==null)   return pRootOfTree;
        //1.将左子树构成双链表,并返回该链表的头节点(左子树最左边的节点)
        TreeNode left=Convert1(pRootOfTree.left);

        //2、定位到左链表的最后一个节点(左子树最右边的节点)
        TreeNode p=left; // 创建临时结点p来寻找左链表最后一个结点(左子树最右结点)
        while(p!=null &&p.right!=null){
            p=p.right;
        }

        //3、如果左子树链表不为空,则将当前root追加到左子树链表后
        if(left!=null){
            p.right=pRootOfTree;
            pRootOfTree.left=p;
        }

        //4、将右子树构造成双向链表,并返回链表头结点(右子树最左边的节点)
        TreeNode right=Convert1(pRootOfTree.right);

        //5、如果右子树链表不为空,将右子树链表追加到当前root后
        if(right!=null){
            pRootOfTree.right=right;
            right.left=pRootOfTree;
        }

        //6、根据左子树链表是否为空返回的整体双向链表的头节点
        return (left==null)?pRootOfTree:left;
    }

解法二:类似于中序遍历

public DoublyListNode bstToDoublyList1(TreeNode root) {
        if(root==null)  return null;
        Stack<TreeNode> stack=new Stack<>();
        TreeNode curNode=root;
        DoublyListNode pre=null; //保存中序遍历结点顺序上的上一个结点
        DoublyListNode newHead=null;
        boolean isFirst=true;
        while(curNode!=null || !stack.isEmpty()) {
            if (curNode != null) {
                stack.push(curNode);
                curNode = curNode.left;
            } else {
                curNode = stack.pop();
                if (isFirst) {
                    newHead = new DoublyListNode(curNode.val);
                    pre = newHead;
                    isFirst = false;
                } else {
                    DoublyListNode p=new DoublyListNode(curNode.val);
                    pre.next=p;
                    p.prev=pre;
                    pre=p;
                }
                curNode=curNode.right;
            }
        }
        return newHead;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值