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 相关文章推荐
phpsir 开发 一个检测百度关键字网站排名的python 程序
Sep 17 Python
python批量制作雷达图的实现方法
Jul 26 Python
浅谈python对象数据的读写权限
Sep 12 Python
如何高效使用Python字典的方法详解
Aug 31 Python
Python中turtle作图示例
Nov 15 Python
Linux CentOS Python开发环境搭建教程
Nov 28 Python
使用OpCode绕过Python沙箱的方法详解
Sep 03 Python
Python转换itertools.chain对象为数组的方法
Feb 07 Python
浅谈Django QuerySet对象(模型.objects)的常用方法
Mar 28 Python
Tensorflow中k.gradients()和tf.stop_gradient()用法说明
Jun 10 Python
python脚本定时发送邮件
Dec 22 Python
Pytorch 如何实现常用正则化
May 27 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的一些小问题
2010/07/03 PHP
php插入中文到sqlserver 2008里出现乱码的解决办法分享
2012/07/19 PHP
PHP中读取文件的8种方法和代码实例
2014/08/05 PHP
CL vs ForZe BO5 第三场 2.13
2021/03/10 DOTA
js实现的网页颜色代码表全集
2007/07/17 Javascript
js用闭包遍历树状数组的方法
2014/03/19 Javascript
jQuery select表单提交省市区城市三级联动核心代码
2014/06/09 Javascript
jQuery插件开发精品教程(让你的jQuery更上一个台阶)
2015/11/07 Javascript
深入浅析JavaScript字符串操作方法 slice、substr、substring及其IE兼容性
2015/12/16 Javascript
详细分析Javascript中创建对象的四种方式
2016/08/17 Javascript
jQuery 获取遍历获取table中每一个tr中的第一个td的方法
2016/10/05 Javascript
jQuery简单自定义图片轮播插件及用法示例
2016/11/21 Javascript
微信小程序 轮播图swiper详解及实例(源码下载)
2017/01/11 Javascript
BootStrap Datepicker 插件修改为默认中文的实现方法
2017/02/10 Javascript
解决vuecli3.0热更新失效的问题
2018/09/19 Javascript
微信小程序使用map组件实现路线规划功能示例
2019/01/22 Javascript
js get和post请求实现代码解析
2020/02/06 Javascript
JS出现404错误原理及解决方案
2020/07/01 Javascript
详解webpack的文件监听实现(热更新)
2020/09/11 Javascript
Python中dictionary items()系列函数的用法实例
2014/08/21 Python
Windows下Python3.6安装第三方模块的方法
2018/11/22 Python
django session完成状态保持的方法
2018/11/27 Python
python 利用pywifi模块实现连接网络破解wifi密码实时监控网络
2019/09/16 Python
python产生模拟数据faker库的使用详解
2020/11/04 Python
详解matplotlib绘图样式(style)初探
2021/02/03 Python
css3实现3D色子翻转特效
2014/12/23 HTML / CSS
检测浏览器对HTML5和CSS3支持度的方法
2015/06/25 HTML / CSS
如何在发生故障的节点上重新安装 SQL Server
2013/03/14 面试题
信息专业本科生个人的自我评价
2013/10/28 职场文书
党员的自我评价范文
2014/01/02 职场文书
采购主管岗位职责
2014/02/01 职场文书
趣味运动会广播稿
2014/09/13 职场文书
校长师德表现自我评价
2015/03/05 职场文书
大学生社会实践感想
2015/08/11 职场文书
教导处教学工作总结
2015/08/12 职场文书
HTML基础详解(下)
2021/10/16 HTML / CSS