题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
简化题目
这道题就是二叉搜索数->双向链表。
看下面的图 大串题目秒懂啊有没有。
思路分析
首先,二叉搜索树 要变成有序双向链表,肯定中序遍历没的说。
遍历的途中,给数之间加上指针,最后再加头尾指针就行了。
步骤
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