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

该博客介绍了如何将一棵二叉搜索树转换为有序的双向循环链表,主要分为两个步骤:中序遍历获取排序节点队列,然后组装成双向链表。过程中不创建新节点,只调整原有节点的指针。提供的代码实现了这一转换,并通过了测试。
摘要由CSDN通过智能技术生成

1.题目描述

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

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

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

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

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

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

2.1 解题思路

题目给定一棵二叉搜索树,并要求在原节点基础上将其变成排好序的双向链表,并返回值最小的节点。按照题意需要完成两步:第一步对二叉搜索树的节点进行排序,第二步将节点连接成双向链表。由于题目给定的是二叉搜索树,因此可以二叉搜索树中序遍历便能够从小到大获取到节点,利用这一性质便能够完成第一步,遍历同时将节点放入队列中,用于组装双向链表。

获取到排好序的节点队列之后便开始组装双向链表,队列的第一个节点便是需要返回的头节点,之后节点的 left 指向队列中当前节点的前一个节点, right 只想队列中当前节点的下一个节点,直到队列为空。此时再把对头节点和队尾节点连接上就完成题目要求。

以题目给出示例为例,首先进行中序遍历,得到节点队列 [1, 2, 3, 4, 5]

然后在从队列中获取头节点,再依次遍历队列,将上一节点 pre 的 right 指向队列弹出的当前节点 curr,再将当前节点的 left 指向上一节点。完成这一操作后将 pre 指向当前节点,继续便利队列,直到队列中的节点全部弹出。

最后一步就是将收尾节点进行连接,此时完成双向循环链表组装。

2.2 代码

class Solution {
    Queue<Node> queue = new LinkedList<>();

    public Node treeToDoublyList(Node root) {
        if (root == null) {
            return null;
        }
        process(root);
        // 弹出队头节点作为头节点,并使用 pre 指向前一个节点
        Node head = queue.poll();
        Node pre = head;
        while (!queue.isEmpty()) {
            // 从队列弹出队头,然后将前一节点和当前节点进行连接
            Node curr = queue.poll();
            pre.right = curr;
            curr.left = pre;
            pre = curr;
        }
        // 队列弹出完成后进行收尾连接
        pre.right = head;
        head.left = pre;
        return head;
    }

    public void process(Node root) {
        if (root == null) {
            return;
        }
        process(root.left);
        // 中序遍历,将节点放入队列中
        queue.offer(root);
        process(root.right);
    }
}

2.3 测试结果

通过测试

3.总结

  • 利用二叉搜索树中序遍历性质获取排序后的节点队列
  • 再使用节点队列组装双向循环链表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值