Python数据结构与算法之二叉树结构定义与遍历方法详解


Posted in Python onDecember 12, 2017

本文实例讲述了Python数据结构与算法之二叉树结构定义与遍历方法。分享给大家供大家参考,具体如下:

先序遍历,中序遍历,后序遍历 ,区别在于三条核心语句的位置

层序遍历  采用队列的遍历操作第一次访问根,在访问根的左孩子,接着访问根的有孩子,然后下一层 自左向右一一访问同层的结点

# 先序遍历
# 访问结点,遍历左子树,如果左子树为空,则遍历右子树,
# 如果右子树为空,则向上走到一个可以向右走的结点,继续该过程
preorder(t):
  if t:
    print t.value
    preorder t.L
    preorder t.R
# 中序遍历
# 从根开始,一直走向左下方,直到无结点可以走则停下,访问该节点
# 然后走向右下方到结点,继续走向左下方:如果结点无右孩子,则向上走回父亲结点
inorder(t):
  inorder(t.L)
  print t.value
  inorder(t.R)
# 后序遍历
inorder(t):
  inorder(t.L)
  inorder(t.R)
  print t.value
# 二叉树结点类型
class BTNode:
  def __init__(self,value,lft=None,rgt=None):
    self.value = value
    self.lft = lft     # 结点左分支 BTNode
    self.rgt = rgt     # 结点右分支 BTNode

为了方便起见,定义一些打印操作

class BinTree():
  def __init__(self):
    self.root = None  # 创建一个空的二叉树
  def isEmpty(self):   # 判断二叉树是否为空
    if self.root is None: return True
    else: return False
  def makeBT(self,bt,L=None,R=None):    # 从当前结点创建二叉树
    bt.lft = L
    bt.rgt = R
  def returnBTdict(self):       # 返回二叉树的字典模式
    if self.isEmpty(): 
      return None
    def rec(bt=None,R=True):
      if R==True:
        bt = self.root
        return {'root':{'value':bt.value,"L":rec(bt.lft,False),
                        "R":rec(bt.rgt,False)} }
      else:
        if bt==None:
          return None
        else:
          return {"value":bt.value,
              "L":rec(bt.lft,False) if bt.lft != None else None,
              "R":rec(bt.rgt,False) if bt.rgt != None else None}
      return None
    return rec()
  def __repr__(self):       # 将二叉树结构打印为字典结构
    return str(self.returnBTdict())

下面是各种遍历方法,添加到树的类中

def printT_VLR(self,bt=None,rec_count = 0):   # 输出二叉树结构(先序遍历)
    # rec_count 用于计算递归深度 以便输出最后的换行符
    """
    # 先序遍历
    # 访问结点,遍历左子树,如果左子树为空,则遍历右子树,
    # 如果右子树为空,则向上走到一个可以向右走的结点,继续该过程
    preorder(t):
      if t:
        print t.value
        preorder t.L
        preorder t.R
    """
    if bt==None: 
      bt = self.root
      print bt.value,
    btL, btR = bt.lft, bt.rgt
    if btL != None:
      print btL.value,;  rec_count += 1;   self.printT_VLR(btL,rec_count);   rec_count -= 1
    if btR != None:
      print btR.value,;  rec_count += 1;   self.printT_VLR(btR,rec_count);   rec_count -= 1
    if rec_count == 0:
      print "\n"
def printT_LVR(self,bt=None):
    """
    # 中序遍历
    # 从根开始,一直走向左下方,直到无结点可以走则停下,访问该节点
    # 然后走向右下方到结点,继续走向左下方:如果结点无右孩子,则向上走回父亲结点
    inorder(t):
      inorder(t.L)
      print t.value
      inorder(t.R)
    """
    if bt==None:
      bt = self.root
    btL, btR = bt.lft, bt.rgt
    if btL != None:
      self.printT_LVR(btL)
    print bt.value,
    if btR != None:
      self.printT_LVR(btR)
def printT_LRV(self,bt=None):
    """
    # 后序遍历
    inorder(t):
      inorder(t.L)
      inorder(t.R)
      print t.value
    """
    if bt==None:
      bt = self.root
    btL, btR = bt.lft, bt.rgt
    if btL != None:
      self.printT_LRV(btL)
    if btR != None:
      self.printT_LRV(btR)
    print bt.value,
def printT_levelorder(self):
    """
    层序遍历 采用队列的遍历操作
    第一次访问根,在访问根的左孩子,接着访问根的有孩子,然后下一层
    自左向右一一访问同层的结点
    """
    btdict = self.returnBTdict()
    q = []
    q.append(btdict['root'])
    while q:
      tn = q.pop(0)  # 从队列中弹出一个结点(也是一个字典)
      print tn["value"],
      if tn["L"]!=None:
        q.append(tn["L"])
      if tn["R"]!=None:
        q.append(tn["R"])

测试打印效果

def test():
  bt = BinTree()
#   btns = [BTNode(v) for v in "+*E*D/CAB"]   # 层序输入
#   bt.root = btns[0]
#   bt.makeBT(btns[0], L=btns[1], R=btns[2])
#   bt.makeBT(btns[1], L=btns[3], R=btns[4])
#   bt.makeBT(btns[3], L=btns[5], R=btns[6])
#   bt.makeBT(btns[5], L=btns[7], R=btns[8])
  btns = [BTNode(v) for v in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]]
  bt.root = btns[0]
  bt.makeBT(btns[0], L=btns[1], R=btns[2])
  bt.makeBT(btns[1], L=btns[3], R=btns[4])
  bt.makeBT(btns[2], L=btns[5], R=btns[6])
  bt.makeBT(btns[3], L=btns[7], R=btns[8])
  bt.makeBT(btns[4], L=btns[9], R=btns[10])
  bt.makeBT(btns[5], L=btns[11], R=btns[12])
  bt.makeBT(btns[6], L=btns[13], R=btns[14])

输出:

{'root': {'R': {'R': {'R': {'R': None, 'L': None, 'value': 15}, 'L': {'R': None, 'L': None, 'value': 14}, 'value': 7}, 'L': {'R': {'R': None, 'L': None, 'value': 13}, 'L': {'R': None, 'L': None, 'value': 12}, 'value': 6}, 'value': 3}, 'L': {'R': {'R': {'R': None, 'L': None, 'value': 11}, 'L': {'R': None, 'L': None, 'value': 10}, 'value': 5}, 'L': {'R': {'R': None, 'L': None, 'value': 9}, 'L': {'R': None, 'L': None, 'value': 8}, 'value': 4}, 'value': 2}, 'value': 1}}

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
Python模块学习 datetime介绍
Aug 27 Python
Python中os和shutil模块实用方法集锦
May 13 Python
Python字符串详细介绍
May 09 Python
python基于pygame实现响应游戏中事件的方法(附源码)
Nov 11 Python
Python求算数平方根和约数的方法汇总
Mar 09 Python
利用Python开发实现简单的记事本
Nov 15 Python
python字典的遍历3种方法详解
Aug 10 Python
python实现的爬取电影下载链接功能示例
Aug 26 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
Jan 14 Python
python通过对字典的排序,对json字段进行排序的实例
Feb 27 Python
详解Python 中的 defaultdict 数据类型
Feb 22 Python
python实现大文本文件分割成多个小文件
Apr 20 Python
Python数据结构与算法之图的基本实现及迭代器实例详解
Dec 12 #Python
Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
Dec 12 #Python
你真的了解Python的random模块吗?
Dec 12 #Python
Python判断两个对象相等的原理
Dec 12 #Python
浅谈Django REST Framework限速
Dec 12 #Python
Django admin美化插件suit使用示例
Dec 12 #Python
Django admin实现图书管理系统菜鸟级教程完整实例
Dec 12 #Python
You might like
PHP模拟post提交数据方法汇总
2016/02/16 PHP
Laravel5.1数据库连接、创建数据库、创建model及创建控制器的方法
2016/03/29 PHP
php中请求url的五种方法总结
2017/07/13 PHP
php实现的生成迷宫与迷宫寻址算法完整实例
2017/11/06 PHP
PHP判断是否是微信打开,浏览器打开的方法
2018/03/14 PHP
解决Laravel无法使用COOKIE和SESSION的问题
2019/10/16 PHP
jquery1.4后 jqDrag 拖动 不可用
2010/02/06 Javascript
javascript与webservice的通信实现代码
2010/12/25 Javascript
文本框水印提示效果的简单实现代码
2014/02/22 Javascript
jQuery修改class属性和CSS样式整理
2015/01/30 Javascript
Node.js中的流(Stream)介绍
2015/03/30 Javascript
JS+CSS实现类似QQ好友及黑名单效果的树型菜单
2015/09/22 Javascript
JS上传组件FileUpload自定义模板的使用方法
2016/05/10 Javascript
微信 java 实现js-sdk 图片上传下载完整流程
2016/10/21 Javascript
jQuery.datatables.js插件用法及api实例详解
2016/10/28 Javascript
etmvc+jQuery EasyUI+combobox多值操作实现角色授权实例
2016/11/09 Javascript
Angular.js实现多个checkbox只能选择一个的方法示例
2017/02/24 Javascript
jquery插件ContextMenu设置右键菜单
2017/03/13 Javascript
代码详解javascript模块加载器
2018/03/04 Javascript
利用原生的JavaScript实现简单拼图游戏
2018/11/18 Javascript
nodejs微信开发之自动回复的实现
2019/03/17 NodeJs
说说如何利用 Node.js 代理解决跨域问题
2019/04/22 Javascript
带你使用webpack快速构建web项目的方法
2020/11/12 Javascript
Windows中安装使用Virtualenv来创建独立Python环境
2016/05/31 Python
浅析Python pandas模块输出每行中间省略号问题
2018/07/03 Python
Python3自动生成MySQL数据字典的markdown文本的实现
2020/05/07 Python
完美解决pycharm 不显示代码提示问题
2020/06/02 Python
Agoda.com官方网站:便宜预订全球酒店,高达80%的折扣
2018/04/04 全球购物
在对linux系统分区进行格式化时需要对磁盘簇(或i节点密度)的大小进行选择,请说明选择的原则
2012/11/24 面试题
大门门卫岗位职责
2013/11/30 职场文书
《望洞庭》教学反思
2014/02/16 职场文书
爱耳日宣传活动总结
2014/07/05 职场文书
财务助理岗位职责范本
2014/10/09 职场文书
个人委托函范文
2015/01/29 职场文书
2015年共青团工作总结
2015/05/15 职场文书
班主任班级管理心得体会
2016/01/07 职场文书