Python 二叉樹的層序建立與三種遍歷實(shí)現(xiàn)詳解
前言
二叉樹(Binary Tree)時(shí)數(shù)據(jù)結(jié)構(gòu)中一個(gè)非常重要的結(jié)構(gòu),其具有。。。。(此處省略好多字)。。。。等的優(yōu)良特點(diǎn)。
之前在刷LeetCode的時(shí)候把有關(guān)樹的題目全部跳過(guò)了,(ORZ:我這種連數(shù)據(jù)結(jié)構(gòu)都不會(huì)的人刷j8Leetcode啊?。。。?/p>
所以 ?。?!敲黑板了?。?!今天我就在B站看了數(shù)據(jù)結(jié)構(gòu)中關(guān)于樹的內(nèi)容后,又用我淺薄的Python大法來(lái)實(shí)現(xiàn)一些樹的建立和遍歷。
關(guān)于樹的建立我覺得層序建立對(duì)于使用者來(lái)說(shuō)最為直觀,輸入很好寫。(好吧,我是看LeetCode中的樹輸入都是采用層序輸入覺得非常好)
樹節(jié)點(diǎn)定義
代碼來(lái)
class BSTreeNode(object): def __init__(self, data): self.val = data self.leftChild = None self.rightChild = None
這一段代碼太好理解了好吧,就不BB了。
二叉樹層序建立
不多說(shuō),先上代碼
# 建立二叉樹是以層序遍歷方式輸入,節(jié)點(diǎn)不存在時(shí)以 'None' 表示 def creatTree(nodeList): if nodeList[0] == None: return None head = BSTreeNode(nodeList[0]) Nodes = [head] j = 1 for node in Nodes: if node != None: node.leftChild = (BSTreeNode(nodeList[j]) if nodeList[j] != None else None) Nodes.append(node.leftChild) j += 1 if j == len(nodeList): return head node.rightChild = (BSTreeNode(nodeList[j])if nodeList[j] != None else None) j += 1 Nodes.append(node.rightChild) if j == len(nodeList): return head
creatTree即為層序建立二叉樹的函數(shù),傳入的參數(shù)為一個(gè)層序遍歷的數(shù)組,就是將樹節(jié)點(diǎn)從左往右,從上往下一次放入數(shù)組中,如果某個(gè)節(jié)點(diǎn)不存在則用None來(lái)表示。
比如:
圖所示的二叉樹則需輸入a = [1,2,3,4,5,None,6,None,None,7,8],接下來(lái)將會(huì)以這個(gè)二叉樹為例講解代碼。
- 第3-4行,判斷根節(jié)點(diǎn)是否為空。 如果根節(jié)點(diǎn)都為空,那樹(shuo)就(ge)不(j)存(8)在了,直接返回就好了。
- 第5行,將元素列表中的第一個(gè)元素取出新建根節(jié)點(diǎn),最后返回的即為根節(jié)點(diǎn)
- 第6行,創(chuàng)建了一個(gè)Nodes列表中,用于存放樹中的節(jié)點(diǎn),每生成一個(gè)節(jié)點(diǎn)就將其放入該列表中,可以看成是一個(gè)隊(duì)列(這么說(shuō)好像也不是特別規(guī)范,因?yàn)楹竺嬷皇侨×斜碇械脑兀瑳]有彈出首元素),此處將根節(jié)點(diǎn)存入。
- 第7行,創(chuàng)建變量j用于nodeList中元素的索引,初始為1.因?yàn)榈?個(gè)元素已經(jīng)創(chuàng)建根節(jié)點(diǎn)了。
- 第8行,依次取出Nodes列表中的節(jié)點(diǎn),對(duì)其創(chuàng)建左子節(jié)點(diǎn)和右子節(jié)點(diǎn)
- 第9行,首先判斷取出的Nodes是否為空,如果為空,說(shuō)明此處沒有節(jié)點(diǎn),就無(wú)需創(chuàng)建子節(jié)點(diǎn),否則進(jìn)行子節(jié)點(diǎn)的創(chuàng)建
- 第10行,為該節(jié)點(diǎn)創(chuàng)建左節(jié)點(diǎn),其值就是索引j的所對(duì)應(yīng)的值,如果nodeLists[j] == None 說(shuō)明沒有該子節(jié)點(diǎn),就不用創(chuàng)建了,即Child = None
- 第11行,將新建的節(jié)點(diǎn)加入Nodes數(shù)組,使其在for循環(huán)中可以繼續(xù)為其添加子節(jié)點(diǎn)
- 第12行,j加1,這樣剛好使每一個(gè)nodeList的元素對(duì)應(yīng)一個(gè)節(jié)點(diǎn)了
- 第13行,判斷j的值,如果與nodeList值相等說(shuō)明全部節(jié)點(diǎn)已經(jīng)添加完畢了,直接返回head根節(jié)點(diǎn)就完成了樹的建立
- 第15-19行,為節(jié)點(diǎn)添加右節(jié)點(diǎn),與添加左節(jié)點(diǎn)的邏輯是一樣的,就不在贅述了
好了代碼注釋完畢,我們?cè)偻ㄟ^(guò)結(jié)合實(shí)例來(lái)解釋一下:
- nodeList = [1,2,3,4,5,None,6,None,None,7,8],下面節(jié)點(diǎn)統(tǒng)一用n(值)來(lái)表示
- 建立根節(jié)點(diǎn) head = n(1), j=1, len(nodeList) = 11
- 開始for循環(huán):Nodes = [n(1)]
- node為n(1),非空
- nodeList[j]=nodeList[1]=2 非空,所以新建節(jié)點(diǎn)n(2),n(1)的左節(jié)點(diǎn)即為n(2),新建節(jié)點(diǎn)放入Nodes, 則Nodes=[n(1),n(2)] j+1=2, j未溢出
- nodeList[j]=nodeList[2]=3 非空,所以新建節(jié)點(diǎn)n(3),n(1)的右節(jié)點(diǎn)即為n(3),新建節(jié)點(diǎn)放入Nodes, 則Nodes=[n(1),n(2),n(3)], 然后j+1=3, j未溢出
- node為n(2),非空
- nodeList[j]=nodeList[3]=4 非空,所以新建節(jié)點(diǎn)n(4),n(2)的左節(jié)點(diǎn)即為n(4),新建節(jié)點(diǎn)放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4)], j+1=4, j未溢出
- nodeList[j]=nodeList[4]=5 非空,所以新建節(jié)點(diǎn)n(5),n(2)的右節(jié)點(diǎn)即為n(5),新建節(jié)點(diǎn)放入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)的左節(jié)點(diǎn)直接等于None, 同時(shí)將None也放入Nodes, 則Nodes=[n(1),n(2),n(3),n(4),n(5),None] j+1=6, j未溢出
- nodeList[j]=nodeList[6]=6 非空,所以新建節(jié)點(diǎn)n(6),n(3)的右節(jié)點(diǎn)即為n(6),新建節(jié)點(diǎn)放入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)的左節(jié)點(diǎn)直接等于None,同時(shí)將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)的右節(jié)點(diǎn)直接等于None,同時(shí)將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 非空,所以新建節(jié)點(diǎn)n(7),n(5)的左節(jié)點(diǎn)即為n(7),新建節(jié)點(diǎn)放入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 非空,所以新建節(jié)點(diǎn)n(8),n(5)的右節(jié)點(diǎn)即為n(8),新建節(jié)點(diǎn)放入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溢出
- node為n(1),非空
- j溢出,則返回head根節(jié)點(diǎn),結(jié)束二叉樹的建立
PS:如果node為空節(jié)點(diǎn)的話,就會(huì)直接跳過(guò)空節(jié)點(diǎn)。
二叉樹遍歷(神用的遞歸)
1. 前序遍歷
#head為二叉樹的根節(jié)點(diǎn) def PreorderTraverse(head): if head: print(head.val) PreorderTraverse(head.leftChild) PreorderTraverse(head.rightChild)
2. 中序遍歷
#head為二叉樹的根節(jié)點(diǎn) def InorderTrverse(head): if head: InorderTrverse(head.leftChild) print(head.val) InorderTrverse(head.rightChild)
3. 后續(xù)遍歷
#head為二叉樹的根節(jié)點(diǎn) def PostorderTraverse(head): if head: PostorderTraverse(head.leftChild) PostorderTraverse(head.rightChild) print(head.val)
對(duì)中序遍歷,費(fèi)了我九牛二虎之力畫了一個(gè)程序執(zhí)行的圖,紅色箭頭代表程序執(zhí)行的過(guò)程,依然以a = [1,2,3,4,5,None,6,None,None,7,8]為例
這個(gè)圖看上去不是很清楚,右鍵保存到本地看會(huì)清楚很多的,我把每一步遞歸的樹都畫出來(lái)了,這樣更加方便理解。
所以程序打印出來(lái)的順序?yàn)椋? 2 7 5 8 1 3 6
最后,致敬大佬,祝各位學(xué)有所成。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python對(duì)稱的二叉樹多種思路實(shí)現(xiàn)方法
- python3實(shí)現(xiàn)在二叉樹中找出和為某一值的所有路徑(推薦)
- Python實(shí)現(xiàn)二叉樹的最小深度的兩種方法
- Python3 翻轉(zhuǎn)二叉樹的實(shí)現(xiàn)
- Python3實(shí)現(xiàn)二叉樹的最大深度
- Python3 合并二叉樹的實(shí)現(xiàn)
- 用Python實(shí)現(xiàn)二叉樹、二叉樹非遞歸遍歷及繪制的例子
- 基于python二叉樹的構(gòu)造和打印例子
- python3實(shí)現(xiàn)二叉樹的遍歷與遞歸算法解析(小結(jié))
- 如何在Python中創(chuàng)建二叉樹
相關(guān)文章
詳解如何用TensorFlow訓(xùn)練和識(shí)別/分類自定義圖片
這篇文章主要介紹了詳解如何用TensorFlow訓(xùn)練和識(shí)別/分類自定義圖片,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08多個(gè)版本的python共存時(shí)使用pip的正確做法
這篇文章主要介紹了多版本python共存時(shí)使用pip的正確做法,幫助有多個(gè)python版本需求的人可以正確的導(dǎo)包,感興趣的朋友可以了解下2020-10-10Python django使用多進(jìn)程連接mysql錯(cuò)誤的解決方法
這篇文章主要介紹了Python django使用多進(jìn)程連接mysql錯(cuò)誤的解決方法,詳細(xì)的介紹了解決方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10Python實(shí)現(xiàn)批量修改文件時(shí)間屬性
我們有時(shí)候需要修改文件的“修改時(shí)間”?、?“訪問(wèn)時(shí)間”,“創(chuàng)建時(shí)間”?,此時(shí)如果使用Python批量實(shí)現(xiàn)應(yīng)該會(huì)方便很多,下面小編就來(lái)為大家介紹一下具體實(shí)現(xiàn)方法吧2023-11-11Python實(shí)現(xiàn)Wordcloud生成詞云圖的示例
這篇文章主要介紹了Python實(shí)現(xiàn)Wordcloud生成詞云圖的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Python數(shù)據(jù)分析之獲取雙色球歷史信息的方法示例
這篇文章主要介紹了Python數(shù)據(jù)分析之獲取雙色球歷史信息的方法,涉及Python網(wǎng)頁(yè)抓取、正則匹配、文件讀寫及數(shù)值運(yùn)算等相關(guān)操作技巧,需要的朋友可以參考下2018-02-02