zoukankan      html  css  js  c++  java
  • 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("
    ")
    
        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("
    深度优先遍历中的中序遍历结果:")
    tree.inorder(tree.root) # 深度遍历的先序遍历时需要传入当前树的根节点
    print("
    深度优先遍历中的后序遍历结果:")
    tree.postorder(tree.root) # 深度遍历的先序遍历时需要传入当前树的根节点

    运行结果:


    talk is cheap,show me the code
  • 相关阅读:
    Maganto错误Cannot initialize the indexer process的解决方法
    保护单元格内容
    欧几里得算法
    SVN服务端命令行的使用心得
    C++常用数值类型的值范围的宏定义
    代码之谜(三) 运算符
    《越狱》观后感
    R 报错的问题
    代码之谜(二) 语句与表达式
    你为什么薪水那么低(二)之 生产力
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9954224.html
Copyright © 2011-2022 走看看