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

文章目录

  • 题目描述
  • 简化题目
  • 思路分析
  • 完整代码

题目描述

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

简化题目

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

看下面的图 大串题目秒懂啊有没有。
剑指 Offer 36. 二叉搜索树与双向链表_第1张图片

思路分析

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

步骤

1.先中序遍历,

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

2.在根节点处理的地方开始修改。
首先 在不断的 dfs(root.left) 之后,树的指针会变为下图这样:
剑指 Offer 36. 二叉搜索树与双向链表_第2张图片指针会指向做左下角的节点,设这个指针是cur吧。
题目要求返回初始指针,所以这里设置一个head指向,方便后续返回。

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

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

所以当pre为空的时候,必然是初始情况,那么让head指向cur。
当pre不为空的时候,pre和cur所指的两个节点互相建立链表。
看下面的图:
剑指 Offer 36. 二叉搜索树与双向链表_第3张图片

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

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

3.最后处理头尾节点互连
剑指 Offer 36. 二叉搜索树与双向链表_第4张图片
显然

 # 处理头和尾相连
        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


你可能感兴趣的:(链表,数据结构)