樹是數據結構中很是重要的一種,主要的用途是用來提升查找效率,對於要重複查找的狀況效果更佳,如二叉排序樹、FP-樹。node
本篇學習筆記來自:二叉樹及其七種遍歷方式、python遍歷與非遍歷方式實現二叉樹python
介紹:算法
樹的遍歷主要有兩種,一種是深度優先遍歷,像前序、中序、後序;另外一種是廣度優先遍歷,像層次遍歷。數據結構
在樹結構中二者的區別還不是很是明顯,但從樹擴展到有向圖,到無向圖的時候,深度優先搜索和廣度優先搜索的效率和做用仍是有很大不一樣的。 app
深度優先通常用遞歸,廣度優先通常用隊列。通常狀況下能用遞歸實現的算法大部分也能用堆棧來實現。學習
如下面樹圖爲例寫代碼實現:測試
''' 樹的構造 1.遞歸實現先序遍歷、中序遍歷、後序遍歷 2.堆棧實現先序遍歷、中序遍歷、後序遍歷 3.隊列實現層次遍歷 ''' #節點類 class Node(object): __slots__ = 'item','lchild','rchild' def __init__(self,item=None,lchild=None,rchild=None): self.item = item self.lchild = lchild self.rchild = rchild #樹類 class Tree(object): def __init__(self): self.root = root self.myQueue = myQueue #添加樹節點 def add(self,item): node = Node(item) if self.root.item == None: #空則賦值root self.root = node self.myQueue.append(self.root) else: treeNode = self.myQueue[0] #該節點子樹還沒齊 if treeNode.lchild == None: treeNode.lchild = node self.myQueue.append(treeNode.lchild) else: treeNode.rchild = node self.myQueue.append(treeNode.rchild) self.myQueue.pop(0) #若是該節點在右子樹,丟棄該節點 #遞歸實現樹的先序遍歷 def front_digui(self,root): if root == None: return None print(root.item) self.front_digui(root.lchild) self.front_digui(root.rchild) #遞歸實現樹的中序遍歷 def middle_digui(self,root): if root == None: return None self.middle_digui(root.lchild) print(root.item) self.middle_digui(root.rchild) #遞歸實現樹的後序遍歷 def later_digui(self,root): if root == None: return None self.later_digui(root.lchild) self.later_digui(root.rchild) print(root.item) #利用堆棧實現樹的先序遍歷 def front_stack(self, root): if root == None: return myStack = [] node = root while node or myStack: while node: #從根節點開始,一直找它的左子樹 print(node.item) myStack.append(node) node = node.lchild node = myStack.pop() #while結束表示當前節點node爲空,即前一個節點沒有左子樹了 node = node.rchild #開始查看它的右子樹 #利用堆棧實現樹的中序遍歷 def middle_stack(self, root): if root == None: return myStack = [] node = root while node or myStack: while node: #從根節點開始,一直找它的左子樹 myStack.append(node) node = node.lchild node = myStack.pop() #while結束表示當前節點node爲空,即前一個節點沒有左子樹了 print node.item, node = node.rchild #開始查看它的右子樹 #利用堆棧實現樹的後序遍歷 def later_stack(self, root): if root == None: return myStack1 = [] myStack2 = [] node = root myStack1.append(node) while myStack1: #這個while循環的功能是找出後序遍歷的逆序,存在myStack2裏面 node = myStack1.pop() if node.lchild: myStack1.append(node.lchild) if node.rchild: myStack1.append(node.rchild) myStack2.append(node) while myStack2: #將myStack2中的元素出棧,即爲後序遍歷次序 print(myStack2.pop().item) #利用隊列實現樹的層次遍歷 def level_queue(self, root): if root == None: return myQueue = [] node = root myQueue.append(node) while myQueue: node = myQueue.pop(0) print node.item, if node.lchild != None: myQueue.append(node.lchild) if node.rchild != None: myQueue.append(node.rchild) #測試 if __name__ == '__main__': items = range(10) #生成十個數據做爲樹節點 tree = Tree() #新建一個樹對象 for item in items: tree.add(item) #逐個添加樹的節點 print('隊列實現層次遍歷:') tree.level_queue(tree.root) print('\n\n遞歸實現先序遍歷:') tree.front_digui(tree.root) print('\n遞歸實現中序遍歷:') tree.middle_digui(tree.root) print('\n遞歸實現後序遍歷:') tree.later_digui(tree.root) print('\n\n堆棧實現先序遍歷:') tree.front_stack(tree.root) print('\n堆棧實現中序遍歷:') tree.middle_stack(tree.root) print('\n堆棧實現後序遍歷:') tree.later_stack(tree.root)
#輸出結果 隊列實現層次遍歷: 0 1 2 3 4 5 6 7 8 9 遞歸實現先序遍歷: 0 1 3 7 8 4 9 2 5 6 遞歸實現中序遍歷: 7 3 8 1 9 4 0 5 2 6 遞歸實現後序遍歷: 7 8 3 9 4 1 5 6 2 0 堆棧實現先序遍歷: 0 1 3 7 8 4 9 2 5 6 堆棧實現中序遍歷: 7 3 8 1 9 4 0 5 2 6 堆棧實現後序遍歷: 7 8 3 9 4 1 5 6 2 0