博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构之二叉树
阅读量:5055 次
发布时间:2019-06-12

本文共 4756 字,大约阅读时间需要 15 分钟。

 

二叉树是一种简单的树形结构,其每个节点的分支节点数有0,1或2个。如下图T1,T2和T3是三棵二叉树。显然二叉树是一种递归的结构。

不包含任何节点的二叉树为空树,只有一个节点的二叉树称为单点树,一个节点的子节点的个数称为该节点的。如果每个分支节点的度都为2,则称之为满二叉树。T4,T5就是两棵满二叉树。

如果一棵二叉树,除最后一层外,其它层的节点都是满的,而最后一层节点在最左边连续排列,空位都在右边,这样的二叉树叫做完全二叉树,如T6、T7所示。

想要遍历一棵二叉树,有两种不同的策略:深度优先遍历和宽度优先遍历。

其中深度优先遍历策略有三种不同的方式:

先根序遍历:按根节点、左子树、右子树的顺序遍历。

中根序遍历:按左子树、根节点、右子树的顺序遍历。

后根序遍历:按左子树、右子树、根节点的顺序遍历。

代码:

用python实现树的构造和几种遍历算法,虽然不难,不过还是把代码作了一下整理总结。实现功能:

  • 树的构造
  • 递归实现先序遍历、中序遍历、后序遍历
  • 堆栈实现先序遍历、中序遍历、后序遍历
  • 队列实现层次遍历
#coding=utf-8class Node(object):    """节点类"""    def __init__(self, elem=-1, lchild=None, rchild=None):        self.elem = elem        self.lchild = lchild        self.rchild = rchildclass Tree(object):    """树类"""    def __init__(self):        self.root = Node()        self.myQueue = []    def add(self, elem):        """为树添加节点"""        node = Node(elem)        if self.root.elem == -1:  # 如果树是空的,则对根节点赋值            self.root = node            self.myQueue.append(self.root)          else:            treeNode = self.myQueue[0]  # 此结点的子树还没有齐。            if treeNode.lchild == None:                treeNode.lchild = node                self.myQueue.append(treeNode.lchild)            else:                treeNode.rchild = node                self.myQueue.append(treeNode.rchild)                self.myQueue.pop(0)  # 如果该结点存在右子树,将此结点丢弃。                 # x.pop()默认弹出最后一个元素;x.pop(num)为弹出索引为num的元素    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 '\n\n递归实现先序遍历:'    tree.front_digui(tree.root)    print '\n递归实现中序遍历:'     tree.middle_digui(tree.root)    print '\n递归实现后序遍历:'    tree.later_digui(tree.root)    print '\n\n堆栈实现先序遍历:'    tree.front_stack(tree.root)    print '\n堆栈实现中序遍历:'    tree.middle_stack(tree.root)    print '\n堆栈实现后序遍历:'    tree.later_stack(tree.root)
总结:
树的遍历主要有两种,一种是深度优先遍历,像前序、中序、后序;另一种是广度优先遍历,像层次遍历。在树结构中两者的区别还不是非常明显,但从树扩展到有向图,到无向图的时候,深度优先搜索和广度优先搜索的效率和作用还是有很大不同的。
深度优先一般用递归,广度优先一般用队列。一般情况下能用递归实现的算法大部分也能用堆栈来实现。
 
一般用队列来构造树,毕竟树是类似广度优先的;如果非要用递归(类似深度优先)来构造的话,最好在终止条件里设置树深,否则构造的树会偏向左单子树或者右单子树。

 

转载于:https://www.cnblogs.com/nicetoseeyou/p/10439411.html

你可能感兴趣的文章
图解算法时间复杂度
查看>>
UI_搭建MVC
查看>>
一个样例看清楚JQuery子元素选择器children()和find()的差别
查看>>
代码实现导航栏分割线
查看>>
Windows Phone开发(7):当好总舵主 转:http://blog.csdn.net/tcjiaan/article/details/7281421...
查看>>
VS 2010打开设计器出现错误
查看>>
SQLServer 镜像功能完全实现
查看>>
Vue-详解设置路由导航的两种方法
查看>>
一个mysql主从复制的配置案例
查看>>
大数据学习系列(8)-- WordCount+Block+Split+Shuffle+Map+Reduce技术详解
查看>>
Win8 安装VS2012 和 Sql Server失败问题
查看>>
【AS3代码】播放FLV视频流的三步骤!
查看>>
cocos2d-x 2.2.6 之 .xml文件数据读取
查看>>
枚举的使用
查看>>
【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试
查看>>
poi 处理空单元格
查看>>
Android 内存泄漏优化总结
查看>>
luogu4849 寻找宝藏 (cdq分治+dp)
查看>>
日志框架--(一)基础篇
查看>>
关于源程序到可运行程序的过程
查看>>