步驟:
1.在前序序列中找到根節點
2.在中序序列中,根據根節點的位置,區分左右子樹集合
3.分別列出左右子樹的前序序列和中序序列
4.回溯前序序列,重複上述步驟,直到將所有節點集合拆解爲葉子節點
舉例:
前序(根-左-右):1 2 4 7 3 5 6 8
中序(左-根-右):4 7 2 1 5 3 8 6
1.前序第一個數字是整個二叉樹的根節點 ,根節點:1
2.中序序列,以根節點1區分左右子樹集合,左子樹集合:4 7 2,右子樹集合:5 3 8 6
3.左子樹的前序序列:2 4 7,中序序列:4 7 2。右子樹的前序序列:3 5 6 8 ,中序序列: 5 3 8 6
4.根據拆分的前序序列和中序序列,繼續確定根節點,繼續拆分
代碼:
定義二叉樹的類
class TreeNode:
def __init__(self,x):
self.val = x
self.left = None
self.right = None
遞歸重建二叉樹
class Solution:
def reConstructBinaryTree(self, pre, tin):#pre、tin分別是前序序列和中序序列
if len(pre)>0:
root = TreeNode(pre[0]) #前序序列的第一個肯定是當前子樹的根節點
rootidx = tin.index(root.val) #返回根節點在中序序列中的位置
root.left = self.reConstructBinaryTree(pre[1:1+rootidx],tin[:rootidx])#重建左子樹
root.right = self.reConstructBinaryTree(pre[1+rootidx:],tin[rootidx+1:])#重建右子樹
return root
可以採用層序輸出的方式驗證生成的二叉樹是否正確,用先進先出的隊列依次保存層序遍歷到的節點(該方法在類Solution下),然後遍歷每個節點的左子節點和右子節點,代碼實現如下:
def PrintFromTopToBottom(self, root):
ans=[]
if root==None:
return ans
else:
q=[root]
while q:
node=q.pop(0)
ans.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return ans
完整代碼:
class TreeNode:
def __init__(self,x):
self.val = x
self.left = None
self.right = None
class Solution:
def reConstructBinaryTree(self, pre, tin):#pre、tin分別是前序序列和中序序列
if len(pre)>0:
root = TreeNode(pre[0])
rootidx = tin.index(root.val)
root.left = self.reConstructBinaryTree(pre[1:1+rootidx],tin[:rootidx])
root.right = self.reConstructBinaryTree(pre[1+rootidx:],tin[rootidx+1:])
return root
def PrintFromTopToBottom(self, root):
ans=[]
if root==None:
return ans
else:
q=[root]
while q:
node=q.pop(0)
ans.append(node.val)
if node.left:
q.append(node.left)
if node.right:
q.append(node.right)
return ans
pre = [1, 2, 4, 7, 3, 5, 6, 8]
tin = [4, 7, 2, 1, 5, 3, 8, 6]
a = Solution()
root = a.reConstructBinaryTree(pre,tin)
ans = a.PrintFromTopToBottom(root)
print(ans)
輸出: [1, 2, 3, 4, 5, 6, 7, 8]