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

题目描述

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

简化题目

这道题就是二叉搜索数->双向链表。

看下面的图 大串题目秒懂啊有没有。
在这里插入图片描述

思路分析

首先,二叉搜索树 要变成有序双向链表,肯定中序遍历没的说。
遍历的途中,给数之间加上指针,最后再加头尾指针就行了。

步骤

1.先中序遍历,

def dfs(root):
   if not root: return
   dfs(root.left)  # 左
   print(root.val) # 根
   dfs(root.right) # 右

2.在根节点处理的地方开始修改。
首先 在不断的 dfs(root.left) 之后,树的指针会变为下图这样:
在这里插入图片描述

指针会指向最左下角的蓝色节点,也就是整个树中最小的点,设这个指针是cur吧。
题目要求返回初始指针,所以这里设置一个head指向,方便后续返回。

再设置一个pre指针,指向cur的前一个节点,方便两者互相设置链表指向。

那么此时cur指向1,pre就设置为空吧。

所以当pre为空的时候,必然是初始情况,那么让head指向cur。
当pre不为空的时候,pre和cur所指的两个节点互相建立链表。
看下面的图:
在这里插入图片描述

if self.pre:
     self.pre.right = cur
     cur.left = self.pre
else:
     # 刚初始化的情况 需要记录头结点以便后续返回
     self.head = cur

每次处理完要让pre移动到cur的节点,因为后面cur要移动到一下个节点了,pre自然就又是cur的前一个节点了。

3.最后处理头尾节点互连
在这里插入图片描述
显然

 # 处理头和尾相连
        self.head.left = self.pre
        self.pre.right = self.head

完整代码

"""
# Definition for a Node.
class Node:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
"""
class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        if not root:
            return
        def dfs(cur):
            # 中序遍历到最左下角
            if not cur:
                return
      
            dfs(cur.left)
            # 处理中间情况
            if self.pre:
                self.pre.right = cur
                cur.left = self.pre
            else:
                # 刚初始化的情况 需要记录头结点以便后续返回
                self.head = cur
                
            self.pre = cur # 移动pre           
            dfs(cur.right)
        
        self.pre = None
        dfs(root)
        # 处理头和尾相连
        self.head.left = self.pre
        self.pre.right = self.head
        return self.head


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深度不学习!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值