中序遍历 为对二叉树作 “左、根、右” 顺序遍历,递归实现如下:
# 打印中序遍历
def dfs(root):
if not root: return
dfs(root.left) # 左
print(root.val) # 根
dfs(root.right) # 右
解题思路:
本文解法基于性质:二叉搜索树的中序遍历为 递增序列 。
将 二叉搜索树 转换成一个 “排序的循环双向链表” ,其中包含三个要素:
排序链表: 节点应从小到大排序,因此应使用 中序遍历 “从小到大”访问树的节点。
双向链表: 在构建相邻节点的引用关系时,设前驱节点 pre 和当前节点 cur ,不仅应构建 pre.right = cur ,也应构建 cur.left = pre 。
循环链表: 设链表头节点 head 和尾节点 tail ,则应构建 head.left = tail 和 tail.right = head 。
class Solution:
def treeToDoublyList(self, root: 'Node') -> 'Node':
def dfs(cur):
if not cur: return
dfs(cur.left) # 递归左子树
if self.pre: # 修改节点引用
self.pre.right, cur.left = cur, self.pre
else: # 记录头节点
self.head = cur
self.pre = cur # 保存 cur
dfs(cur.right) # 递归右子树
if not root: return
self.pre = None
dfs(root)
self.head.left, self.pre.right = self.pre, self.head
return self.head
纠结的点就是,为什么self.pre,self.head表示节点,好像因为力扣定义了Class Node
按下面那样写也可以,不想写nonlocal,就定义成self.xxx
"""
# 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):
def dfs(cur):
nonlocal pre
nonlocal head
if not cur:return
dfs(cur.left)
if pre:
pre.right,cur.left=cur,pre
if pre.val==float("inf"):head=cur
pre=cur
dfs(cur.right)
if not root: return
#self.pre = None
pre=Node(float("inf"))
head=Node(None)
dfs(root)
head.left,pre.right=pre,head
return head