二叉树的深度优先和广度优先遍历

作者: 晓可加油 | 来源:发表于2017-05-29 17:31 被阅读659次

    二叉树遍历

    树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次,我们把这种对所有节点的访问称为遍历(traversal)。那么树的两种重要的遍历模式是深度优先遍历和广度优先遍历,深度优先一般用递归,广度优先一般用队列。一般情况下能用递归实现的算法大部分也能用堆栈来实现。

    深度优先遍历

    对于一颗二叉树,深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
    那么深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。这三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)。我们来给出它们的详细定义,然后举例看看它们的应用。

    先序遍历

    在先序遍历中,我们先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树
    根节点->左子树->右子树

    def preorder(self, root):
          """递归实现先序遍历"""
          if root == None:
              return
          print(root.elem)
          self.preorder(root.lchild)
          self.preorder(root.rchild)
    

    中序遍历

    在中序遍历中,我们递归使用中序遍历访问左子树,然后访问根节点,最后再递归使用中序遍历访问右子树
    左子树->根节点->右子树

    def inorder(self, root):
          """递归实现中序遍历"""
          if root == None:
              return
          self.inorder(root.lchild)
          print(root.elem)
          self.inorder(root.rchild)
    

    后序遍历

    在后序遍历中,我们先递归使用后序遍历访问左子树和右子树,最后访问根节点
    左子树->右子树->根节点

    def postorder(self, root):
          """递归实现后续遍历"""
          if root == None:
              return
          self.postorder(root.lchild)
          self.postorder(root.rchild)
          print(root.elem)
    
    这里写图片描述

    广度优先遍历(层次遍历)

    从树的root开始,从上到下从从左到右遍历整个树的节点

     def breadth_travel(self):
            """广度优先遍历"""
            if self.root is None:
                return
            else:
                queue = []
                queue.append(self.root)
                while len(queue) > 0:
                    node = queue.pop(0)
                    print(node.item, end=" ")
                    if node.lchild:
                        queue.append(node.lchild)
                    if node.rchild:
                        queue.append(node.rchild)
    

    完整代码

    class Node(object):
        """节点"""
        def __init__(self, item):
            self.item = item
            self.lchild = None
            self.rchild = None
    
    
    class BinaryTree(object):
        """二叉树"""
        def __init__(self, node=None):
            self.root = node
    
        def add(self, item):
            """"""
            if self.root is None:
                self.root = Node(item)
            else:
                queue = []
                queue.append(self.root)
                while len(queue) > 0:
                    node = queue.pop(0)
                    if not node.lchild:
                        node.lchild = Node(item)
                        return
                    else:
                        queue.append(node.lchild)
                    if not node.rchild:
                        node.rchild = Node(item)
                        return
                    else:
                        queue.append(node.rchild)
    
        def breadth_travel(self):
            """广度优先遍历"""
            if self.root is None:
                return
            else:
                queue = []
                queue.append(self.root)
                while len(queue) > 0:
                    node = queue.pop(0)
                    print(node.item, end=" ")
                    if node.lchild:
                        queue.append(node.lchild)
                    if node.rchild:
                        queue.append(node.rchild)
    
        def preorder_travel(self, node):
            """根 左 右"""
            if node:
                print(node.item, end=" ")
                self.preorder_travel(node.lchild)
                self.preorder_travel(node.rchild)
            else:
                return
    
        def inorder_travel(self, node):
            """左 根  右"""
            if node:
                self.inorder_travel(node.lchild)
                print(node.item, end=" ")
                self.inorder_travel(node.rchild)
            else:
                return
    
        def postorder_travel(self, node):
            """左 右 根"""
            if node:
                self.postorder_travel(node.lchild)
                self.postorder_travel(node.rchild)
                print(node.item, end=" ")
            else:
                return
    
    #测试
    if __name__ == '__main__':
        t = BinaryTree()
        t.add(0)
        t.add(1)
        t.add(2)
        t.add(3)
        t.add(4)
        t.add(5)
        t.add(6)
        t.add(7)
        t.add(8)
        t.add(9)
        t.breadth_travel()
        print("")
        t.preorder_travel(t.root)
        print("")
        t.inorder_travel(t.root)
        print("")
        t.postorder_travel(t.root)
        print("")
    
    
    
    
    
    

    相关文章

      网友评论

        本文标题:二叉树的深度优先和广度优先遍历

        本文链接:https://www.haomeiwen.com/subject/xcflfxtx.html