Python --- 二叉樹的層序建立與三種遍歷


二叉樹(Binary Tree)時數據結構中一個非常重要的結構,其具有。。。。(此處省略好多字)。。。。等的優良特點。

之前在刷LeetCode的時候把有關樹的題目全部跳過了,(ORZ:我這種連數據結構都不會的人刷j8Leetcode啊!!!)

所以 !!!敲黑板了!!!今天我就在B站看了數據結構中關於樹的內容后,又用我淺薄的Python大法來實現一些樹的建立和遍歷。


關於樹的建立我覺得層序建立對於使用者來說最為直觀,輸入很好寫。(好吧,我是看LeetCode中的樹輸入都是采用層序輸入覺得非常好)

樹節點定義

代碼來

class BSTreeNode(object):
    def __init__(self, data):
        self.val = data
        self.leftChild = None
        self.rightChild = None

這一段代碼太好理解了好吧,就不BB了。

二叉樹層序建立

不多說,先上代碼

 1 # 建立二叉樹是以層序遍歷方式輸入,節點不存在時以 'None' 表示
 2 def creatTree(nodeList):
 3     if nodeList[0] == None:
 4         return None
 5     head = BSTreeNode(nodeList[0])
 6     Nodes = [head]
 7     j = 1
 8     for node in Nodes:
 9         if node != None:
10             node.leftChild = (BSTreeNode(nodeList[j]) if nodeList[j] != None else None)
11             Nodes.append(node.leftChild)
12             j += 1
13             if j == len(nodeList):
14                 return head
15             node.rightChild = (BSTreeNode(nodeList[j])if nodeList[j] != None else None)
16             j += 1
17             Nodes.append(node.rightChild)
18             if j == len(nodeList):
19                 return head

 

 

 creatTree即為層序建立二叉樹的函數,傳入的參數為一個層序遍歷的數組,就是將樹節點從左往右,從上往下一次放入數組中,如果某個節點不存在則用None來表示。

比如:

所示的二叉樹則需輸a = [1,2,3,4,5,None,6,None,None,7,8],接下來將會以這個二叉樹為例講解代碼。

  • 3-4行,判斷根節點是否為空。 如果根節點都為空,那樹(shuo)就(ge)不(j)存(8)在了,直接返回就好了。
  • 5行,將元素列表中的第一個元素取出新建根節點,最后返回的即為根節點
  • 6行,創建了一個Nodes列表中,用於存放樹中的節點,每生成一個節點就將其放入該列表中,可以看成是一個隊列(這么說好像也不是特別規范,因為后面只是取列表中的元素,沒有彈出首元素),此處將根節點存入。
  • 7行,創建變量j用於nodeList中元素的索引,初始為1.因為第0個元素已經創建根節點了。
  • 8行,依次取出Nodes列表中的節點,對其創建左子節點和右子節點
  • 9行,首先判斷取出的Nodes是否為空,如果為空,說明此處沒有節點,就無需創建子節點,否則進行子節點的創建
  • 10行,為該節點創建左節點,其值就是索引j的所對應的值,如果nodeLists[j] == None 說明沒有該子節點,就不用創建了,即Child = None
  • 11行,將新建的節點加入Nodes數組,使其在for循環中可以繼續為其添加子節點
  • 12行,j加1,這樣剛好使每一個nodeList的元素對應一個節點了
  • 13行,判斷j的值,如果與nodeList值相等說明全部節點已經添加完畢了,直接返回head根節點就完成了樹的建立
  • 15-19行,為節點添加右節點,與添加左節點的邏輯是一樣的,就不在贅述了

好了代碼注釋完畢,我們再通過結合實例來解釋一下:

  •  nodeList = [1,2,3,4,5,None,6,None,None,7,8],下面節點統一用n(值)來表示
  • 建立根節點 head = n(1), j=1, len(nodeList) = 11
  • 開始for循環:Nodes = [n(1)]
    • node為n(1),非空
      • nodeList[j]=nodeList[1]=2 非空,所以新建節點n(2),n(1)的左節點即為n(2),新建節點放入Nodes, 則Nodes=[n(1),n(2)] j+1=2, j未溢出
      • nodeList[j]=nodeList[2]=3 非空,所以新建節點n(3),n(1)的右節點即為n(3),新建節點放入Nodes, 則Nodes=[n(1),n(2),n(3)], 然后j+1=3, j未溢出
    • node為n(2),非空
      • nodeList[j]=nodeList[3]=4 非空,所以新建節點n(4),n(2)的左節點即為n(4),新建節點放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4)], j+1=4, j未溢出
      • nodeList[j]=nodeList[4]=5 非空,所以新建節點n(5),n(2)的右節點即為n(5),新建節點放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5)], j+1=5, j未溢出
    • node為n(3),非空
      • nodeList[j]=nodeList[5]=None 為空,所以n(3)的左節點直接等於None, 同時將None也放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5),None] j+1=6, j未溢出
      • nodeList[j]=nodeList[6]=6 非空,所以新建節點n(6),n(3)的右節點即為n(6),新建節點放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6)], j+1=7, j未溢出 
    • node為n(4),非空
      • nodeList[j]=nodeList[7]=None 為空,所以n(4)的左節點直接等於None,同時將None也放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None], j+1=8, j未溢出
      • nodeList[j]=nodeList[8]=None 為空,所以n(4)的右節點直接等於None,同時將None也放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None,None], j+1=9, j未溢出
    • node為n(5), 非空
      • nodeList[j]=nodeList[9]=7 非空,所以新建節點n(7),n(5)的左節點即為n(7),新建節點放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None,None,n(9)] j+1=10, j未溢出
      • nodeList[j]=nodeList[10]=8 非空,所以新建節點n(8),n(5)的右節點即為n(8),新建節點放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None,None,n(9),n(10)] j+1=11, j溢出
  • j溢出,則返回head根節點,結束二叉樹的建立

  PS:如果node為空節點的話,就會直接跳過空節點。

 

二叉樹遍歷(神用的遞歸)

1. 前序遍歷

 

#head為二叉樹的根節點
def PreorderTraverse(head):
    if head:
        print(head.val)
        PreorderTraverse(head.leftChild)
        PreorderTraverse(head.rightChild)

 

 

2. 中序遍歷

 

#head為二叉樹的根節點
def InorderTrverse(head):
    if head:
        InorderTrverse(head.leftChild)
        print(head.val)
        InorderTrverse(head.rightChild)

  

 

3. 后續遍歷

#head為二叉樹的根節點
def PostorderTraverse(head):
    if head:
        PostorderTraverse(head.leftChild)
        PostorderTraverse(head.rightChild)
        print(head.val)

 

 對中序遍歷,費了我九牛二虎之力畫了一個程序執行的圖,紅色箭頭代表程序執行的過程,依然以a = [1,2,3,4,5,None,6,None,None,7,8]為例

 這個圖看上去不是很清楚,右鍵保存到本地看會清楚很多的,我把每一步遞歸的樹都畫出來了,這樣更加方便理解。

所以程序打印出來的順序為:4 2 7 5 8 1 3 6


 

最后,致敬大佬,祝各位學有所成。

 

【轉載表明出處,謝謝】

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM