二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解题思路:
二叉搜索树:即左子树<根<右子树
10
↙ ↘
6 14
↙ ↘ ↙ ↘
4 8 12 16
双向链表:如 4 ⇆ 6 ⇆ 8 ⇆ 10 ⇆ 12 ⇆ 14 ⇆ 16,其中每个结点都有两个指针,一个指向前一个结点,一个指向后一个结点。
由于树中的每个结点都有两个指针,指向左子树和右子树,刚好可以转换为双向链表中指向前一个结点和后一个结点的指针。
- 按中序遍历(左/根/右),遍历的顺序刚好是有序的,从小到大的。
- 先遍历左子树 则上一个遍历到的结点(last_node),当前遍历到的结点(node)之间的关系为: node.left = last_node; last_node.right = node
- 遍历根节点: 遍历当前结点:last_node = node
- 对右子树实行相同的操作
class Solution:
def Convert(self, pRootOfTree):
if not pRootOfTree:
return None
def solution(pRootOfTree,last_node):
if not pRootOfTree:
return None
#中序遍历
if pRootOfTree.left:
#先遍历左结点,再遍历根结点,因此用一个结点保存遍历过的结点
last_node = solution(pRootOfTree.left,last_node)
#当前结点为pRootOfTree,则他的左结点为上一个遍历的结点
pRootOfTree.left = last_node
#上一个结点为last_node,则她的右结点为当前结点
if last_node:
last_node.right = pRootOfTree
#遍历根节点,更新遍历过的结点
last_node = pRootOfTree
#遍历右子树
if pRootOfTree.right:
last_node = solution(pRootOfTree.right,last_node)
return last_node
solution(pRootOfTree,None)
#链表的头节点为左子树的左节点
head = pRootOfTree
while head.left:
head = head.left
return head
- 中序遍历后将结果存放到数组中,然后遍历数组,将每个指针进行调整。
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def Convert(self, pRootOfTree):
if not pRootOfTree:
return pRootOfTree
p = pRootOfTree
result = []
#中序遍历
def zhongxubianli(pRootOfTree):
if pRootOfTree.left:
zhongxubianli(pRootOfTree.left)
result.append(pRootOfTree)
if pRootOfTree.right:
zhongxubianli(pRootOfTree.right)
zhongxubianli(pRootOfTree)
#遍历数组,修改指针
for i in range(len(result)):
if i-1 >= 0:
result[i].left = result[i-1]
if i+1 < len(result):
result[i].right = result[i+1]
return result[0]