zoukankan      html  css  js  c++  java
  • python实现二叉树和它的七种遍历

    介绍:

    树是数据结构中很重要的一种,基本的用途是用来提高查找效率,对于要反复查找的情况效果更佳,如二叉排序树、FP-树。

    另外能够用来提高编码效率,如哈弗曼树。
    这里写图片描写叙述


    代码:

    用python实现树的构造和几种遍历算法,尽管不难。只是还是把代码作了一下整理总结。

    实现功能:

    • 树的构造
    • 递归实现先序遍历、中序遍历、后序遍历
    • 堆栈实现先序遍历、中序遍历、后序遍历
    • 队列实现层次遍历
    #coding=utf-8
    
    class Node(object):
        """节点类"""
        def __init__(self, elem=-1, lchild=None, rchild=None):
            self.elem = elem
            self.lchild = lchild
            self.rchild = rchild
    
    
    class Tree(object):
        """树类"""
        def __init__(self):
            self.root = Node()
    
    
        def add(self, elem):
            """为树加入节点"""
            node = Node(elem)
            if self.root.elem == -1:            #假设树是空的。则对根节点赋值
                self.root = node
            else:                     
                myQueue = []
                treeNode = self.root
                myQueue.append(treeNode)
                while myQueue:                      #对已有的节点进行层次遍历
                    treeNode = myQueue.pop(0)
                    if treeNode.lchild == None:
                        treeNode.lchild = node
                        return
                    elif treeNode.rchild == None:
                        treeNode.rchild = node
                        return
                    else:
                        myQueue.append(treeNode.lchild)
                        myQueue.append(treeNode.rchild)
    
    
        def front_digui(self, root):
            """利用递归实现树的先序遍历"""
            if root == None:
                return
            print root.elem,
            self.front_digui(root.lchild)
            self.front_digui(root.rchild)
    
    
        def middle_digui(self, root):
            """利用递归实现树的中序遍历"""
            if root == None:
                return
            self.middle_digui(root.lchild)
            print root.elem,
            self.middle_digui(root.rchild)
    
    
        def later_digui(self, root):
            """利用递归实现树的后序遍历"""
            if root == None:
                return
            self.later_digui(root.lchild)
            self.later_digui(root.rchild)
            print root.elem,
    
    
        def front_stack(self, root):
            """利用堆栈实现树的先序遍历"""
            if root == None:
                return
            myStack = []
            node = root
            while node or myStack:
                while node:                     #从根节点開始,一直找它的左子树
                    print node.elem,
                    myStack.append(node)
                    node = node.lchild
                node = myStack.pop()            #while结束表示当前节点node为空,即前一个节点没有左子树了
                node = node.rchild                  #開始查看它的右子树
    
    
        def middle_stack(self, root):
            """利用堆栈实现树的中序遍历"""
            if root == None:
                return
            myStack = []
            node = root
            while node or myStack:
                while node:                     #从根节点開始。一直找它的左子树
                    myStack.append(node)
                    node = node.lchild
                node = myStack.pop()            #while结束表示当前节点node为空。即前一个节点没有左子树了
                print node.elem,
                node = node.rchild                  #開始查看它的右子树
    
    
        def later_stack(self, root):
            """利用堆栈实现树的后序遍历"""
            if root == None:
                return
            myStack1 = []
            myStack2 = []
            node = root
            myStack1.append(node)
            while myStack1:                   #这个while循环的功能是找出后序遍历的逆序,存在myStack2里面
                node = myStack1.pop()
                if node.lchild:
                    myStack1.append(node.lchild)
                if node.rchild:
                    myStack1.append(node.rchild)
                myStack2.append(node)
            while myStack2:                         #将myStack2中的元素出栈,即为后序遍历次序
                print myStack2.pop().elem,
    
    
        def level_queue(self, root):
            """利用队列实现树的层次遍历"""
            if root == None:
                return
            myQueue = []
            node = root
            myQueue.append(node)
            while myQueue:
                node = myQueue.pop(0)
                print node.elem,
                if node.lchild != None:
                    myQueue.append(node.lchild)
                if node.rchild != None:
                    myQueue.append(node.rchild)
    
    
    if __name__ == '__main__':
        """主函数"""
        elems = range(10)           #生成十个数据作为树节点
        tree = Tree()          #新建一个树对象
        for elem in elems:                  
            tree.add(elem)           #逐个加入树的节点
    
        print '队列实现层次遍历:'
        tree.level_queue(tree.root)
    
        print '
    
    递归实现先序遍历:'
        tree.front_digui(tree.root)
        print '
    递归实现中序遍历:' 
        tree.middle_digui(tree.root)
        print '
    递归实现后序遍历:'
        tree.later_digui(tree.root)
    
        print '
    
    堆栈实现先序遍历:'
        tree.front_stack(tree.root)
        print '
    堆栈实现中序遍历:'
        tree.middle_stack(tree.root)
        print '
    堆栈实现后序遍历:'
        tree.later_stack(tree.root)


    总结:

    树的遍历主要有两种,一种是深度优先遍历,像前序、中序、后序;还有一种是广度优先遍历。像层次遍历。在树结构中两者的差别还不是很明显。但从树扩展到有向图。到无向图的时候。深度优先搜索和广度优先搜索的效率和作用还是有很大不同的。


    深度优先一般用递归,广度优先一般用队列。普通情况下能用递归实现的算法大部分也能用堆栈来实现。

    我印象中是有递归构造树的方法。却一直想不出该怎么构造。后来细致想了一下。递归思想有点相似深度优先算法,而树的构造应该是广度优先的。假设用递归的话一定要有个终止条件,比如规定树深等。不然构造出来的树会偏向左单子树或者右单子树。所以一般树的构造还是应该用队列比較好。




    以上说的不够严谨,有错误之处,欢迎指正!


    转载请注明出处,谢谢!

    (原文链接:http://blog.csdn.net/bone_ace/article/details/46718683

  • 相关阅读:
    2018-2-13-安装-aria2
    ..USERstm32f10x.h(428): error: #67: expected a "}" ADC1_2_IRQn = 18, /*!
    zubax_gnss移植到STM32F407
    ChibiOS/RT移植到STM32F407
    arm-none-eabi/bin/ld: build/com.zubax.gnss.elf section `.text' will not fit in region `flash'
    Traceback (most recent call last): File "../zubax_chibios/tools/make_boot_descriptor.py", line 251
    Eclipse 交叉编译环境
    PX4/Pixhawk uORB
    FreeRTOS 任务创建和删除(静态)
    FreeRTOS 任务创建和删除(动态)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5246662.html
Copyright © 2011-2022 走看看