【题目】
对二叉树的节点来说,有本身的值域,有指向左孩子和右孩子的两个指针;对双向链表的节点来说,有本身的值域,有指向上一个节点和下一个节点的指针。在结构上,两种结构有相似性,现在有一棵搜索二叉树,请将其转换为一个有序的双向链表。最后返回转换后的双向链表的头节点。
【基本思路】
方法一。时间复杂度O(N),空间复杂度O(N)。
使用队列等容器收集二叉树中序遍历的结果,收集完毕后在按照队列中的顺序将每个节点串起来。代码实现如下:
#python3.5
def convert1(head):
def inOrderToQueue(head, queue):
if head == None:
return
inOrderToQueue(head.left, queue)
queue.append(head)
inOrderToQueue(head.right, queue)
if head == None:
return None
queue = []
inOrderToQueue(head, queue)
head = queue.pop(0)
head.left = None
newHead = head
while queue:
node = queue.pop(0)
head.right = node
node.left = head
head = node
head.right = None
return newHead
方法二。时间复杂度O(N),空间复杂度O(h)。
利用递归函数。一个头节点为head的二叉树转换成有序双向链表,首先将head的左子树和右子树转换成有序双向链表L1和L2,然后让head节点连接L1链表的尾节点和L2链表的头节点。改写后序递归即可。
问题的关键是如何快速定位一个双向链表的头节点和尾节点,解决的方法是,使双向链表尾节点的right指针指向头节点,递归的时候返回链表的尾节点,这样不仅可以得到链表的尾节点,也可以根据right指针很快的得到头节点。当然,递归结束后要将链表的结构还原。代码实现如下:
def convert2(head):
def process(head):
if head == None:
return
leftE = process(head.left)
rightE = process(head.right)
leftH = None if leftE == None else leftE.right
rightH = None if rightE == None else rightE.right
if leftE != None and rightE != None:
leftE.right = head
head.left = leftE
rightH.left = head
head.right = rightH
rightE.right = leftH
return rightE
elif leftE != None:
leftE.right = head
head.left = leftE
head.right = leftH
return head
elif rightE != None:
head.right = rightH
rightH.left = head
rightE.right = head
return rightE
else:
head.right = head
return head
if head == None:
return None
tail = process(head)
head = tail.right
tail.right = None
return head