import numpy as np
#重建二叉樹
#二叉樹的前序遍歷
preorder = [3,9,20,15,7]
#二叉樹的中序遍歷
inorder = [9,3,15,20,7]
#定義的臨時變量,爲了得到二叉樹中節點個數
#方便後續定義result(存儲重建二叉樹節點的一個二維數組)
p = np.array(preorder)
#存儲重建二叉樹節點的一個二維數組)
result = [[] for i in range(p.shape[0])]
#定義左右子樹節點所需變量爲列表
left = list
right = list
#定義重建二叉樹函數
#第一個參數:前序排列節點
#第二個參數:中序排列節點
#第三個參數:重建樹節點所在深度(此處根定義爲0層)
def Deal(preorder,inorder,count = 0):
pre = np.array(preorder)
ino = np.array(inorder)
#輸出重建以前前序,中序,結果3個變量內容,便於後續分析
print("\n\n")
print(str(count)+"處理前->")
print("Pre:")
print(pre)
print("Ino:")
print(ino)
print("Result:")
print(result)
#遞歸停止條件,即重建二叉樹停止條件爲中序或前序節點序列剩下一個結點
if pre.shape[0] == 1:
result[count].append(preorder[0])
return
if ino.shape[0] == 1:
result[count].append(inorder[0])
return
#定義標誌位變量,以便於在中序序列中找到前序首元素的時候,跳出雙層循環
b = False
#記錄跳出循環那一時刻,前序節點的索引號
iFront = 0
for i in range(pre.shape[0]):
for j in range(ino.shape[0]):
#前序序列和中序序列進行節點匹配
if preorder[i] == inorder[j]:
#一旦匹配,將中序序列進行分割,得到左右子樹
left = inorder[:j]
right = inorder[j+1:]
iFront = i
b = True
break
if b == True:
break
#輸出跳出循環時刻前序節點索引號
print(iFront)
#判斷索引號是非首元素,非首元素的情況下,對前序序列進行分片
if iFront > 0:
preorder = preorder[iFront:]
#輸出剪短後的前序序列,方便分析
print(preorder)
print('<---]')
#將子樹的根節點加入對應層(樹的深度)
result[count].append(preorder[0])
#刪除前序序列中首元素(其已經作爲根節點參加了重建)
del(preorder[0])
#輸出處理後的前序,中序,重建結果,左右子樹,方便邏輯分析
print('\n\n處理後:')
print("Pre:")
print(preorder)
print("Ino:")
print(inorder)
print("Result:")
print(result)
print("Left:")
print(left)
print("Right:")
print(right)
#將樹深度加1,進行新一輪分析重建
count += 1
#對新的左右子樹分別進行重建分析
Deal(preorder,left,count)
Deal(preorder,right,count)
#調用函數對前序序列,中序序列進行分析重建,初始樹深度設爲0
Deal(preorder,inorder,0)
#輸出分析結果
print("\n\nFinal Result:")
print(result)