二叉樹深度優先(DFS)和廣度優先(BFS)
深度優先遍歷:對每一個可能的分支路徑深入到不能再深入為止,而且每個結點只能訪問一次。二叉樹的深度優先遍歷的非遞歸的通用做法是采用棧,要特別注意的是,二叉樹的深度優先遍歷比較特殊,可以細分為先序遍歷、中序遍歷、后序遍歷。具體說明如下:
- 先序(根)遍歷:對任一子樹,先訪問根,然后遍歷其左子樹,最后遍歷其右子樹。
- 中序(根)遍歷:對任一子樹,先遍歷其左子樹,然后訪問根,最后遍歷其右子樹。
- 后序(根)遍歷:對任一子樹,先遍歷其左子樹,然后遍歷其右子樹,最后訪問根。
DFS的Python算法描述:
def depth_tree(tree_node):
""" # 深度優先過程 :param tree_node: :return: """
if tree_node is not None:
print(tree_node._data)
if tree_node._left is not None:
return depth_tree(tree_node._left)
if tree_node._right is not None:
return depth_tree(tree_node._right)
注:
scrapy
默認是通過深度優先來實現的。
廣度優先遍歷:又叫層次遍歷,從上往下對每一層依次訪問,在每一層中,從左往右(也可以從右往左)訪問結點,訪問完一層就進入下一層,直到沒有結點可以訪問為止。廣度優先遍歷的非遞歸的通用做法是采用隊列。
BFS的算法描述:
def level_queue(root):
""" # 廣度優先過程 :param root: :return: """
if root is None:
return
my_queue = []
node = root
my_queue.append(node)
while my_queue:
node = my_queue.pop(0)
print(node.elem)
if node.lchild is not None:
my_queue.append(node.lchild)
if node.rchild is not None:
my_queue.append(node.rchild)
區別:
通常深度優先搜索法遍歷時不全部保留結點,遍歷完后的結點從棧中彈出刪去,這樣,一般在棧中存儲的結點數就是二叉樹的深度值,因此它占用空間較少。所以,當搜索樹的結點較多,用其它方法易產生內存溢出時,深度優先搜索不失為一種有效的求解方法。 但深度優先搜素算法有回溯操作(即有入棧、出棧操作),運行速度慢。
廣度優先搜索算法,一般需存儲產生的所有結點,占用的存儲空間要比深度優先搜索大得多,因此,程序設計中,必須考慮溢出和節省內存空間的問題。但廣度優先搜索法一般無回溯操作,即入棧和出棧的操作,所以運行速度比深度優先搜索要快些。