1. 程式人生 > >python 資料結構與演算法 day05 二叉樹的深度優先遍歷(縱向)

python 資料結構與演算法 day05 二叉樹的深度優先遍歷(縱向)

1. 二叉樹深度優先遍歷三種方式

 

不同於樹的廣度優先遍歷(一層一層的走,同一層從左到右走完開始走下一層的橫向遍歷方式),深度優先遍歷是一條路走到黑,然後再走下一條; 

 

先序遍歷根節點--左子節點---右子節點(先從根節點開始,走左子樹,對這個左子樹依然按照根節點--左子節點---右子節點的順序遍歷,然後左邊的子樹走完,按照同樣的方式遍歷:根節點---左子節點--右子節點);

中序遍歷:左子節點--根節點---右子節點;

後序遍歷:左子節點----右子節點---根節點

 

先序遍歷,中序遍歷 ,後序遍歷永遠是根據根節點的順序來說的,左子節點永遠在右子節點的前面;

 

 

2. 深度優先遍歷程式碼實現:

class Node(object):
    """建立一個節點類"""
    def __init__(self,item):
        self.item=item  # 建立的能掛在樹上的節點 得有一個data資料域 還得有兩個左右節點指向左右子節點(因為實現的是二叉樹,每個節點最多兩個子節點)
        self.lchild=None  # 當前節點的左子節點
        self.rchild=None  # 當前節點的右子節點

class Tree(object):
    """構建二叉樹
""" def __init__(self): self.root=None # 構建的一棵樹首先得有一個根節點(就像連結串列有一個頭節點self.__head) def add(self,item): """實現二叉樹新增元素""" node=Node(item) queue=[] # 佇列(把當前樹的所有節點都存放在佇列中,然後挨個取出佇列中的元素,判斷該節點的做右子節點是否都存在,不存在就掛在當前節點的相應自節點位置上) if self.root is None: # 如果當前樹是一個空樹 直接就把要新增的元素放在根節點上就好啦
self.root=node return queue.append(self.root) # 先把樹的根節點放在佇列中,也就是從根節點開始遍歷 while queue: cur_node=queue.pop(0) # queue佇列存放的是當前樹所有節點(沒有被遍歷過的) 然後挨個取出節點,遍歷做右子節點 if cur_node.lchild is None: cur_node.lchild=node return else: queue.append(cur_node.lchild) if cur_node.rchild is None: cur_node.rchild=node return else: queue.append(cur_node.rchild) def breadth_travel(self): """二叉樹的廣度優先遍歷""" if self.root is None: # 如果最開始是一個空樹,廣度優先遍歷,沒法遍歷元素,所以直接返回ok return queue=[self.root] # 對於二叉樹不是空樹的情況下,需要把當前樹的所有節點都新增到佇列中,然後遍歷,首先把二叉樹的根節點新增到佇列中 while queue: cur_node=queue.pop(0) # 首先取出根節點,然後後續的取出樹中的其他節點 print(cur_node.item,end=" ") # 打印出當前節點的元素值 if cur_node.lchild is not None: # 如果當前節點的左子節點非空,就把左子節點新增到需要遍歷的佇列queue中 queue.append(cur_node.lchild) if cur_node.rchild is not None: queue.append(cur_node.rchild) print("\n") def preorder(self,node): # 因為使用遞迴在進行先序遍歷時,對於左子節點 右子節點部分都會當成一棵樹,然後這棵樹的根節點都是會發生變化的,所以呼叫自身時傳了一個引數 """先序遍歷""" if node is None: return print(node.item,end=" ") # 先列印根節點 self.preorder(node.lchild) # 左子樹(把node.lchild 這個node節點的左子節點當作左子樹的根節點) self.preorder(node.rchild) # 右子節點 def inorder(self,node): """深度優先遍歷的中序遍歷""" if node is None: return self.inorder(node.lchild) # 先處理左子樹 print(node.item,end=" ") # 再處理根節點 self.inorder(node.rchild) # 最後處理右子樹 def postorder(self,node): """深度優先遍歷的後序遍歷""" if node is None: return self.postorder(node.lchild) # 先處理左子樹 self.postorder(node.rchild) # 再處理右子樹 print(node.item,end=" ") # 最後處理根節點 tree=Tree() tree.add(0) tree.add(1) tree.add(2) tree.add(3) tree.add(4) tree.add(5) tree.add(6) tree.add(7) tree.add(8) tree.add(9) print("廣度優先遍歷結果:") tree.breadth_travel() # 廣度優先遍歷 print("深度優先遍歷中的先序遍歷結果:") tree.preorder(tree.root) # 深度遍歷的先序遍歷時需要傳入當前樹的根節點 print("\n深度優先遍歷中的中序遍歷結果:") tree.inorder(tree.root) # 深度遍歷的先序遍歷時需要傳入當前樹的根節點 print("\n深度優先遍歷中的後序遍歷結果:") tree.postorder(tree.root) # 深度遍歷的先序遍歷時需要傳入當前樹的根節點

 

執行結果: