前面我們介紹了隊列、堆棧、鏈表,你親自動手實踐了嗎?今天我們來到了樹的部分,樹在數據結構中是非常重要的一部分,樹的應用有很多很多,樹的種類也有很多很多,今天我們就先來創建一個普通的樹。其他各種各樣的樹將來我將會一一為大家介紹,記得關注我的文章哦~
首先,樹的形狀就是類似這個樣子的:
它最頂上面的點叫做樹的根節點,一棵樹也只能有一個根節點,在節點下面可以有多個子節點,子節點的數量,我們這里不做要求,而沒有子節點的節點叫做葉子節點。
好,關于樹的基本概念就介紹到這里了,話多千遍不如動手做一遍,接下來我們邊做邊學,我們來創建一棵樹:
樹
# 定義一個普通的樹類
class Tree:
def __init__(self, data):
self.data = data
self.children = []
def get(self):
return self.data
def set(self):
return self.data
def addChild(self, child):
self.children.append(child)
def getChildren(self):
return self.children
這就是我們定義好的樹類了,并給樹添加了三個方法,分別是獲取節點數據、設置節點數據、添加子節點、獲取子節點。
這里的樹類其實是一個節點類,很多個這樣的節點可以構成一棵樹,而我們就用根節點來代表這顆樹。
接下來我們實例化一棵樹:
# 初始化一個樹
tree = Tree(0)
# 添加三個子節點
tree.addChild(Tree(1))
tree.addChild(Tree(2))
tree.addChild(Tree(3))
children = tree.getChildren()
# 每個子節點添加兩個子節點
children[0].addChild(Tree(4))
children[0].addChild(Tree(5))
children[1].addChild(Tree(6))
children[1].addChild(Tree(7))
children[2].addChild(Tree(8))
children[2].addChild(Tree(9))
OK,我們的樹已經實例化好了,我們先來對它分別采用遞歸和非遞歸的方式進行廣度優先遍歷:
廣度優先遍歷
廣度優先遍歷,就是從上往下,一層一層從左到右對樹進行遍歷。
在用非遞歸方式進行廣度優先遍歷的時候,我們需要用到前面介紹過的隊列類型,所以我們來定義一個隊列類:
# 用以實現廣度優先遍歷
class Queue():
def __init__(self):
self.__list = list()
def isEmpty(self):
return self.__list == []
def push(self, data):
self.__list.append(data)
def pop(self):
if self.isEmpty():
return False
return self.__list.pop(0)
用隊列實現廣度優先遍歷
利用隊列我們只要在節點出隊的時候讓該節點的子節點入隊即可。
# 廣度優先遍歷
def breadthFirst(tree):
queue = Queue()
queue.push(tree)
result = []
while not queue.isEmpty():
node = queue.pop()
result.append(node.data)
for c in node.getChildren():
queue.push(c)
return result
調用一下:
print(breadthFirst(tree))
輸出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
遞歸實現廣度優先遍歷
# 遞歸方式實現廣度優先遍歷
def breadthFirstByRecursion(gen, index=0, nextGen=[], result=[]):
if type(gen) == Tree:
gen = [gen]
result.append(gen[index].data)
children = gen[index].getChildren()
nextGen += children
if index == len(gen)-1:
if nextGen == []:
return
else:
gen = nextGen
nextGen = []
index = 0
else:
index += 1
breadthFirstByRecursion(gen, index, nextGen,result)
return result
調用一下:
print(breadthFirstByRecursion(tree))
輸出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
深度優先遍歷
深度優先遍歷,就是從上往下,從左到右,先遍歷節點的子節點再遍歷節點的兄弟節點。
采用非遞歸方式實現深度優先遍歷呢,我們需要用到前面介紹過的堆棧結構,所以我們現在定義一個堆棧類吧:
# 用以實現深度優先遍歷
class Stack():
def __init__(self):
self.__list = list()
def isEmpty(self):
return self.__list == []
def push(self, data):
self.__list.append(data)
def pop(self):
if self.isEmpty():
return False
return self.__list.pop()
利用堆棧實現深度優先遍歷
實現深度優先遍歷,我們只要在節點出棧的時候把該節點的子節點從左到右壓入堆棧即可。
# 深度優先遍歷
def depthFirst(tree):
stack = Stack()
stack.push(tree)
result = []
while not stack.isEmpty():
node = stack.pop()
result.append(node.data)
children = node.getChildren()
children = reversed(children)
for c in children:
stack.push(c)
return result
調用一下:
# 深度優先遍歷
print(depthFirst(tree))
輸出:
[0, 1, 4, 5, 2, 6, 7, 3, 8, 9]
遞歸實現深度優先遍歷
# 遞歸方式實現深度優先遍歷
def depthFirstByRecursion(tree, result=[]):
result.append(tree.data)
children = tree.getChildren()
for c in children:
depthFirstByRecursion(c, result)
return result
調用一下:
print(depthFirstByRecursion(tree))
輸出:
[0, 1, 4, 5, 2, 6, 7, 3, 8, 9]
好啦,今天我們的樹就介紹到這里了,對于廣度優先遍歷的遞歸實現,你有更好的方法嗎?請留言告訴我吧。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
