二叉树的BFS和DFS

1. Depth First Search(DFS)

其过程简要来说就是对每一个可能的分支路径深入到不能深入为止,而且每个节点只能访问一次

对于上面的例子,DFS的结果就是A,B,D,E,I,C,F,G,H.(假设先走子节点的的左侧)。

深度优先搜索遍历各个节点,需要使用栈的数据结构,其特点是后进先出。整个遍历过程如下:

1)首先将A节点压入栈中,stack(A);

2)将A节点弹出,同时将A节点的C、B压入栈中,此时B在栈的顶部,stack(C,B);

3)将B节点弹出,同时将B的子节点E、D压入栈中,此时D在栈的顶部,stack(C,E,D);

4)将D节点弹出,D没有子节点,此时E在栈的顶部,stack(C,E);

5)将E节点弹出,同时将E的子节点I压入,stack(C,I);

......依次往下,最终遍历完成。

python代码:

# -*- coding: utf-8 -*-
class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

class Tree_Method:
    
    def create_tree(self, arr):
        '''
        利用二叉树的三个组成部分:根节点-左子树-右子树;
        传入的arr是一个多维列表,每一维最大为3,
        每一维中的内容依次表示根节点-左子树-右子树。然后递归的进行构建
        '''

        length = len(arr)  #计算每一维的大小
        root = TreeNode(arr[0]) #获取每一维的根节点
        if length >= 2:         #判断是否有左子树
            root.left = self.create_tree(arr[1])
        if length >= 3:         #判断是否有右子树
            root.right = self.create_tree(arr[2])
        return root

    def DFS(self, root):
        '''
        深度优先遍历,即先访问根节点,然后遍历左子树接着遍历右子树。
        主要利用栈的特点,先将右子树压栈,再将左子树压栈,这样左子树就位于栈顶,
        可以结点的左子树先与右子树被遍历。
        '''

        if root == None:
            return None
        stack = []
        '''用列表模仿入栈'''
        stack.append(root)          
        while stack:
            '''将栈顶元素出栈'''
            current_node = stack.pop()
            print(current_node.value, end=' ')
            '''判断该节点是否有右孩子,有就入栈'''
            if current_node.right:
                stack.append(current_node.right)
            '''判断该节点是否有左孩子,有就入栈'''
            if current_node.left:
                stack.append(current_node.left)

if __name__ == '__main__':
    arr = [2,[3,[4],[5]],[2,[4,[7]],[3]]]
    op = Tree_Method()
    tree = op.create_tree(arr)
    print('深度优先遍历:', end='')
    op.DFS(tree)
            

!!!DFS对于树来说就是前序遍历,中序遍历,后序遍历!!!

# -*- coding: utf-8 -*-
class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

    def preOrder(self, root):
        '''先序遍历'''
        if root == None:
            return None
        print(root.value)
        self.preOrder(root.left)
        self.preOrder(root.right)

    def minOrder(self, root):
        '''中序遍历'''
        if root == None:
            return None
        self.minOrder(root.left)
        print(root.value)
        self.minOrder(root.right)

    def postOrder(self, root):
        '''后序遍历'''
        if root == None:
            return None
        self.postOrder(root.left)
        self.postOrder(root.right)
        print(root.value)

2. Breadth First Search(BFS)  

!!!BFS对于树来说就是层次遍历!!!

其过程简单来说是对每一层节点依次访问,访问完一层进入下一层,而且每个节点只能访问一次

对于上面的例子,BFS的结果就是A,B,C,D,E,F,G,H,I(假设每层节点从左到右访问)。

广度优先遍历各个节点,需要使用队列(Queue)这种数据结构,其特点是先进先出。也可以使用双端队列,区别就是双端队列首尾都可以插入和弹出节点。整个遍历过程如下:

1)首先将A节点插入队列中,queue(A);

2)将A节点弹出,同时将A的子结点B、C插入队列中,此时B在队列首部,C在队列尾部,queue(B,C);

3)将B节点弹出,同时将B的子结点D、E插入队列中,此时C在队列首部,E在队列尾部,queue(C,D,E);

4)将C节点弹出,同时将C的子节点F,G,H插入队列中,此时D在队列首部,H在队列尾部,queue(D,E,F,G,H);

5)将D节点弹出,D没有子节点,此时E在队列首部,H在队列尾部,queue(E,F,G,H);

.......依次往下,最终遍历完成。

python代码:

# -*- coding: utf-8 -*-
class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

class Tree_Method:
    
    def create_tree(self, arr):
        '''
        利用二叉树的三个组成部分:根节点-左子树-右子树;
        传入的arr是一个多维列表,每一维最大为3,
        每一维中的内容依次表示根节点-左子树-右子树。然后递归的进行构建
        '''

        length = len(arr)  #计算每一维的大小
        root = TreeNode(arr[0]) #获取每一维的根节点
        if length >= 2:         #判断是否有左子树
            root.left = self.create_tree(arr[1])
        if length >= 3:         #判断是否有右子树
            root.right = self.create_tree(arr[2])
        return root

    def BFS(self, root):
        '''
        广度优先遍历,即从上到下,从左到右遍历。
        主要利用队列先进先出的特性,入队的时候,是按根左右的顺序,那么只要按照这个顺序出队就可以了
        '''

        if root == None:
            return None
        queue = []
        '''用列表模仿入队'''
        queue.append(root)          
        while queue:
            '''将队首元素出栈'''
            current_node = queue.pop(0)
            print(current_node.value, end=' ')
            '''判断该节点是否有左孩子,有就入队'''
            if current_node.left:
                queue.append(current_node.left)
            '''判断该节点是否有右孩子,有就入队'''
            if current_node.right:
                queue.append(current_node.right)

if __name__ == '__main__':
    arr = [2,[3,[4],[5]],[2,[4,[7]],[3]]]
    op = Tree_Method()
    tree = op.create_tree(arr)
    print('广度优先遍历:', end='')
    op.BFS(tree)

猜你喜欢

转载自blog.csdn.net/mengmengdajuanjuan/article/details/84313361