Python 二叉树的层序建立与三种遍历实现详解


Posted in Python onJuly 29, 2019

前言

二叉树(Binary Tree)时数据结构中一个非常重要的结构,其具有。。。。(此处省略好多字)。。。。等的优良特点。

之前在刷LeetCode的时候把有关树的题目全部跳过了,(ORZ:我这种连数据结构都不会的人刷j8Leetcode啊!!!)

所以 !!!敲黑板了!!!今天我就在B站看了数据结构中关于树的内容后,又用我浅薄的Python大法来实现一些树的建立和遍历。

关于树的建立我觉得层序建立对于使用者来说最为直观,输入很好写。(好吧,我是看LeetCode中的树输入都是采用层序输入觉得非常好)

树节点定义

代码来

class BSTreeNode(object):
 def __init__(self, data):
  self.val = data
  self.leftChild = None
  self.rightChild = None

这一段代码太好理解了好吧,就不BB了。

二叉树层序建立

不多说,先上代码

# 建立二叉树是以层序遍历方式输入,节点不存在时以 'None' 表示
def creatTree(nodeList):
 if nodeList[0] == None:
  return None
 head = BSTreeNode(nodeList[0])
 Nodes = [head]
 j = 1
 for node in Nodes:
  if node != None:
   node.leftChild = (BSTreeNode(nodeList[j]) if nodeList[j] != None else None)
   Nodes.append(node.leftChild)
   j += 1
   if j == len(nodeList):
    return head
   node.rightChild = (BSTreeNode(nodeList[j])if nodeList[j] != None else None)
   j += 1
   Nodes.append(node.rightChild)
   if j == len(nodeList):
    return head

creatTree即为层序建立二叉树的函数,传入的参数为一个层序遍历的数组,就是将树节点从左往右,从上往下一次放入数组中,如果某个节点不存在则用None来表示。

比如:

Python 二叉树的层序建立与三种遍历实现详解

图所示的二叉树则需输入a = [1,2,3,4,5,None,6,None,None,7,8],接下来将会以这个二叉树为例讲解代码。

  • 第3-4行,判断根节点是否为空。 如果根节点都为空,那树(shuo)就(ge)不(j)存(8)在了,直接返回就好了。
  • 第5行,将元素列表中的第一个元素取出新建根节点,最后返回的即为根节点
  • 第6行,创建了一个Nodes列表中,用于存放树中的节点,每生成一个节点就将其放入该列表中,可以看成是一个队列(这么说好像也不是特别规范,因为后面只是取列表中的元素,没有弹出首元素),此处将根节点存入。
  • 第7行,创建变量j用于nodeList中元素的索引,初始为1.因为第0个元素已经创建根节点了。
  • 第8行,依次取出Nodes列表中的节点,对其创建左子节点和右子节点
  • 第9行,首先判断取出的Nodes是否为空,如果为空,说明此处没有节点,就无需创建子节点,否则进行子节点的创建
  • 第10行,为该节点创建左节点,其值就是索引j的所对应的值,如果nodeLists[j] == None 说明没有该子节点,就不用创建了,即Child = None
  • 第11行,将新建的节点加入Nodes数组,使其在for循环中可以继续为其添加子节点
  • 第12行,j加1,这样刚好使每一个nodeList的元素对应一个节点了
  • 第13行,判断j的值,如果与nodeList值相等说明全部节点已经添加完毕了,直接返回head根节点就完成了树的建立
  • 第15-19行,为节点添加右节点,与添加左节点的逻辑是一样的,就不在赘述了

好了代码注释完毕,我们再通过结合实例来解释一下:

Python 二叉树的层序建立与三种遍历实现详解

  • nodeList = [1,2,3,4,5,None,6,None,None,7,8],下面节点统一用n(值)来表示
  • 建立根节点 head = n(1), j=1, len(nodeList) = 11
  • 开始for循环:Nodes = [n(1)]
    • node为n(1),非空
      • nodeList[j]=nodeList[1]=2 非空,所以新建节点n(2),n(1)的左节点即为n(2),新建节点放入Nodes, 则Nodes=[n(1),n(2)] j+1=2, j未溢出
      • nodeList[j]=nodeList[2]=3 非空,所以新建节点n(3),n(1)的右节点即为n(3),新建节点放入Nodes, 则Nodes=[n(1),n(2),n(3)], 然后j+1=3, j未溢出
    • node为n(2),非空
      • nodeList[j]=nodeList[3]=4 非空,所以新建节点n(4),n(2)的左节点即为n(4),新建节点放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4)], j+1=4, j未溢出
      • nodeList[j]=nodeList[4]=5 非空,所以新建节点n(5),n(2)的右节点即为n(5),新建节点放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4),n(5)], j+1=5, j未溢出
    • node为n(3),非空
      • nodeList[j]=nodeList[5]=None 为空,所以n(3)的左节点直接等于None, 同时将None也放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4),n(5),None] j+1=6, j未溢出
      • nodeList[j]=nodeList[6]=6 非空,所以新建节点n(6),n(3)的右节点即为n(6),新建节点放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6)], j+1=7, j未溢出 
    • node为n(4),非空
      • nodeList[j]=nodeList[7]=None 为空,所以n(4)的左节点直接等于None,同时将None也放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None], j+1=8, j未溢出
      • nodeList[j]=nodeList[8]=None 为空,所以n(4)的右节点直接等于None,同时将None也放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None,None], j+1=9, j未溢出
    • node为n(5), 非空
      • nodeList[j]=nodeList[9]=7 非空,所以新建节点n(7),n(5)的左节点即为n(7),新建节点放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None,None,n(9)] j+1=10, j未溢出
      • nodeList[j]=nodeList[10]=8 非空,所以新建节点n(8),n(5)的右节点即为n(8),新建节点放入Nodes, 则Nodes=[n(1),n(2),n(3),n(4),n(5),None,n(6),None,None,n(9),n(10)] j+1=11, j溢出
  • j溢出,则返回head根节点,结束二叉树的建立

PS:如果node为空节点的话,就会直接跳过空节点。

二叉树遍历(神用的递归)

1. 前序遍历

#head为二叉树的根节点
def PreorderTraverse(head):
 if head:
  print(head.val)
  PreorderTraverse(head.leftChild)
  PreorderTraverse(head.rightChild)

2. 中序遍历

#head为二叉树的根节点
def InorderTrverse(head):
 if head:
  InorderTrverse(head.leftChild)
  print(head.val)
  InorderTrverse(head.rightChild)

3. 后续遍历

#head为二叉树的根节点
def PostorderTraverse(head):
 if head:
  PostorderTraverse(head.leftChild)
  PostorderTraverse(head.rightChild)
  print(head.val)

对中序遍历,费了我九牛二虎之力画了一个程序执行的图,红色箭头代表程序执行的过程,依然以a = [1,2,3,4,5,None,6,None,None,7,8]为例

Python 二叉树的层序建立与三种遍历实现详解

这个图看上去不是很清楚,右键保存到本地看会清楚很多的,我把每一步递归的树都画出来了,这样更加方便理解。

所以程序打印出来的顺序为:4 2 7 5 8 1 3 6

最后,致敬大佬,祝各位学有所成。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python连接MySQL、MongoDB、Redis、memcache等数据库的方法
Nov 15 Python
Python和GO语言实现的消息摘要算法示例
Mar 10 Python
Python选择排序、冒泡排序、合并排序代码实例
Apr 10 Python
python动态网页批量爬取
Feb 14 Python
Python脚本实现自动发带图的微博
Apr 27 Python
python中利用zfill方法自动给数字前面补0
Apr 10 Python
Python3导入自定义模块的三种方法详解
Apr 13 Python
python 应用之Pycharm 新建模板默认添加编码格式-作者-时间等信息【推荐】
Jun 17 Python
python使用tomorrow实现多线程的例子
Jul 20 Python
使用pycharm运行flask应用程序的详细教程
Jun 07 Python
python基础之函数的定义和调用
Oct 24 Python
Python 数据可视化之Matplotlib详解
Nov 02 Python
Python完成哈夫曼树编码过程及原理详解
Jul 29 #Python
Python秒算24点实现及原理详解
Jul 29 #Python
django之状态保持-使用redis存储session的例子
Jul 28 #Python
django 通过URL访问上传的文件方法
Jul 28 #Python
django使用admin站点上传图片的实例
Jul 28 #Python
Python中变量的输入输出实例代码详解
Jul 28 #Python
对django中foreignkey的简单使用详解
Jul 28 #Python
You might like
PHP计划任务、定时执行任务的实现代码
2011/04/23 PHP
smarty高级特性之过滤器的使用方法
2015/12/25 PHP
如何写php守护进程(Daemon)
2015/12/30 PHP
学习PHP Cookie处理函数
2016/08/09 PHP
关于laravel 子查询 & join的使用
2019/10/16 PHP
js操作Xml(向服务器发送Xml,处理服务器返回的Xml)(IE下有效)
2009/01/30 Javascript
锋利的jQuery 要点归纳(二) jQuery中的DOM操作(下)
2010/03/23 Javascript
JavaScript之appendChild、insertBefore和insertAfter使用说明
2010/12/30 Javascript
Jquery动态改变图片IMG的src地址示例
2013/06/25 Javascript
jquery中邮箱地址 URL网站地址正则验证实例代码
2013/09/15 Javascript
js实现目录定位正文示例
2013/11/14 Javascript
jquery如何把数组变为字符串传到服务端并处理
2014/04/30 Javascript
JavaScript无缝滚动效果的实例代码
2017/03/27 Javascript
微信小程序picker组件下拉框选择input输入框的实例
2017/09/20 Javascript
jquery 时间戳转日期过程详解
2019/10/12 jQuery
js实现旋转的星空效果
2019/11/01 Javascript
原生js实现随机点餐效果
2019/12/10 Javascript
vue实现移动端图片上传功能
2019/12/23 Javascript
javascript中可能用得到的全部的排序算法
2020/03/05 Javascript
js实现简单放大镜效果
2020/03/07 Javascript
js面向对象封装级联下拉菜单列表的实现步骤
2021/02/08 Javascript
Python实现多线程HTTP下载器示例
2017/02/11 Python
python脚本监控Tomcat服务器的方法
2018/07/06 Python
Python实现平行坐标图的绘制(plotly)方式
2019/11/22 Python
基于html5 canvas实现漫天飞雪效果实例
2014/09/10 HTML / CSS
照片礼物和装饰:MyPhoto
2019/11/02 全球购物
《二泉映月》教学反思
2014/04/15 职场文书
2014年党员自我评议总结
2014/09/23 职场文书
工作失误检讨书(经典集锦版)
2014/10/17 职场文书
2015元旦晚会主持人开场白+结束语
2014/12/14 职场文书
毕业实习感受与体会
2015/05/26 职场文书
格列佛游记读书笔记
2015/06/30 职场文书
2016年大学迎新工作总结
2015/10/14 职场文书
市级三好生竞选稿
2015/11/21 职场文书
Elasticsearch 数据类型及管理
2022/04/19 Python
java版 联机五子棋游戏
2022/05/04 Java/Android