剑指 Offer 36. 二叉搜索树与双向链表

文章描述了一种方法,通过中序遍历和迭代,将二叉搜索树转换为排序的循环双向链表,过程中不创建新节点,仅调整原有节点的指针。关键在于利用二叉搜索树的特性及中序遍历的顺序,以及正确处理头结点和尾结点的连接。
摘要由CSDN通过智能技术生成

剑指 Offer 36. 二叉搜索树与双向链表

难度中等619

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

为了让您更好地理解问题,以下面的二叉搜索树为例:

我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。

下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。

特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。

思路

本题还是利用其二叉搜索树的特点,中序遍历的序列是递增有序的.,但是中间形成双向链表,确实不好想,但是看完题解之后瞬间清晰.

根据题意 : 将该二叉搜索树转换成一个排序的循环双向链表,也就是说头尾也得相连.

既然是利用二叉搜索树中序遍历,我之前总结过,需要一个prev前驱指针(也要根据当前节点与前驱结点有没有关系而决定).

具体步骤 :

  • 使用中序遍历
  • 记录prev前驱指针,head头结点,记住head千万不能每次都动,要不成死循环了,head一定是刚开始确定,后面就不能动了.
  • 在cur不为空的情况下
    • 前驱结点为null,意味着刚开始遍历,设置头结点
    • 前驱结点不为null,意味着当前节点能够和前驱形成双向链表关系(prev的右孩子链上cur,cur的左孩子链上prev)
    • 然后更新前驱结点--->进行迭代
  • 中序遍历完成后,进行头结点head与尾结点prev进行相连,形成双向循环关系

 

class Solution {
    private Node prev = null;
    private Node head = null;
    private void dfs(Node cur) {
        if(cur==null) return;
        //利用中序遍历的序列递增特点
        dfs(cur.left);
        if(prev==null) {//刚开始记录头结点
            head = cur;
        }else {//形成双向链表
            prev.right = cur;
            cur.left = prev;
        }
        //迭代记录节点前序
        prev = cur;
        dfs(cur.right);
    }
    public Node treeToDoublyList(Node root) {
        if(root==null) return root;
        dfs(root);
        //头尾相连
        head.left = prev;
        prev.right = head;
        //返回新头
        return head;
    }
}

使用 cur.left = prev ,prev.right = cur这样才能够利用其中序遍历,来帮助我们自然地形成形成双向链表.

还需要注意的是 : head一定在一开始就固定,否则成环,导致死循环,至于双向链表肯定和当前节点,前驱节点相关,要想形成关联,那就需要操作其左右指针,对于这种题二叉树转链表的,肯定是与前驱节点相关,下一步就要想操作其左指针还是操作其右指针,哪一个指针不动,就自然形成了链表.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值