题目:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路:
注意题干,不能创造新节点的意思就是 希望直接把二叉树变成双向链表,也就是要改变树内部节点的左右指针的连接顺序。二叉排序树的特点是 左子树<根节点<右子树,而且没有重复节点。这意味着,如果我们就按照中序遍历:左根右 来遍历,就能刚好得到一个有序的节点,按该顺序转换成链表即可。
先把中序遍历的代码写出来:
self.Convert(pRootOfTree.left)
pRootOfTree
self.Convert(pRootOfTree.right
这里要先在类里构造一个临时节点用来充当链表的头指针和尾指针,这里头最后用来返回该链表,尾指针代表链表的当前值的位置。
def __init__(self):
self.listHead=None
self.listTail=None
如图,在遍历完一个左子树后,指针会在左子树的右边的叶子节点(3),接下来要遍历子树上一层的根节点(4),但树本身结构是根节点(4) 连着 子树的根节点(2),于是在这里要修改树的左右连接,让节点3和节点4互相连接。
if(self.listHead==None):
self.listHead=pRootOfTree
self.listTail=pRootOfTree
else:
self.listTail.right=pRootOfTree
pRootOfTree.left=self.listTail
self.listTail=self.listTail.right
完整的代码,还包括 向右向左打印链表,利用前序和中序构建二叉树等部分。
)
# -*- coding:utf-8 -*-
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def __init__(self):
self.listHead=None
self.listTail=None
def Convert(self, pRootOfTree):
if(pRootOfTree==None):
return None
self.Convert(pRootOfTree.left)
if(self.listHead==None):
self.listHead=pRootOfTree
self.listTail=pRootOfTree
else:
self.listTail.right=pRootOfTree
pRootOfTree.left=self.listTail
self.listTail=self.listTail.right
self.Convert(pRootOfTree.right)
return self.listHead
# 返回构造的TreeNode根节点
def reConstructBinaryTree(self, pre, tin):
if(len(pre)==0 or len(tin)==0):
return None
root=TreeNode(pre[0])
for i,item in enumerate(tin):
if(item==root.val):
root.left=self.reConstructBinaryTree(pre[1:i+1],tin[:i])
root.right=self.reConstructBinaryTree(pre[i+1:],tin[i+1:])
return root
def printTree(self,head):
if(head==None):
return None
while(head.right!=None):
print(head.val,end=" ")
head=head.right
while(head!=None):
print(head.val,end=" ")
head=head.left
if __name__=='__main__':
sl=Solution()
pre=[4,2,1,3,6,5,7]
tin=[1,2,3,4,5,6,7]
treeRoot1 = sl.reConstructBinaryTree(pre, tin)
head=sl.Convert(treeRoot1)
sl.printTree(head)
参考:https://blog.csdn.net/u010005281/article/details/79657259