python实现二叉树遍历

2023-11-19

使用python实现二叉树的四种遍历:前序、中序、后序和层次遍历

以遍历下图二叉树为例:

 

 

1、树的构造 

代码如下:

#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()
        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)  # 如果该结点存在右子树,将此结点丢弃。

 

2、前序遍历

思想:先访问根节点,再先序遍历左子树,然后再先序遍历右子树。总的来说是根—左—右
代码如下:

def front_digui(self, root):
        """利用递归实现树的先序遍历"""
        if root == None:
            return
        print (root.elem)
        self.front_digui(root.lchild)
        self.front_digui(root.rchild)

3、中序遍历

思想:先中序访问左子树,然后访问根,最后中序访问右子树。总的来说是左—根—右
代码如下:

def middle_digui(self, root):
        """利用递归实现树的中序遍历"""
        if root == None:
            return
        self.middle_digui(root.lchild)
        print(root.elem)
        self.middle_digui(root.rchild)

4、后序遍历

思想:先后序访问左子树,然后后序访问右子树,最后访问根。总的来说是左—右—根
代码如下:

def later_digui(self, root):
        """利用递归实现树的后序遍历"""
        if root == None:
            return
        self.later_digui(root.lchild)
        self.later_digui(root.rchild)
        print(root.elem)

完整代码:

#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()
        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)  # 如果该结点存在右子树,将此结点丢弃。


    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)

 


树的遍历主要有两种,一种是深度优先遍历,像前序、中序、后序;另一种是广度优先遍历,像层次遍历。在树结构中两者的区别还不是非常明显,但从树扩展到有向图,到无向图的时候,深度优先搜索和广度优先搜索的效率和作用还是有很大不同的。 
深度优先一般用递归,广度优先一般用队列。一般情况下能用递归实现的算法大部分也能用堆栈来实现。
 

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python实现二叉树遍历 的相关文章

  • ElasticSearch 6.3版本(ES)查询人名关键字不拆词查询

    ElasticSearch 6 3版本 ES 查询关键字不拆词查询 类似mysql 的 like 语句 mysql的sql语法类似如下 采用大量like和locate语法 进行模糊查询 导致查询一个需要8秒多 通过ES优化后 总的查询在1秒
  • postman中进行SHA1或MD5签名

    大部分接口为了防御重放攻击 往往使用SHA1或者MD5对请求进行签名 例如 我们有如下请求 Request URL http xx xx xx xx nonce 123 timestamp 123 Body xxx xxx signatur
  • ESP8266(果云科技的开发板源码)

    ESP8266 果云科技的开发板源码 TOC 最近调试果云科技的老板子ESP8266开发板 比较老了 调试串口输入很麻烦 因为API函数很麻烦 源码已上传 请下载 下面是代码 File uart c Copyright 2013 2016
  • jxls Excel表格导出( 模板导出多个sheet)

    使用模板来导出excel表格 1 使用jxls core jar包来实现 jxls core不支持POI4以上的版本 1 1 maven
  • 在微服务项目中,Spring Security 比 Shiro 强在哪?

    Spring Security 和Shiro的区别
  • LDAP协议

    1 LDAP是Lightweight Directory Access Protocol的缩写 顾名思义 它是指轻量级目录访问协议 这个主要是相对另一目录访问协议X 500而言的 LDAP略去了x 500中许多不太常用的功能 且以TCP I
  • 程序的链接

    程序的链接是一个非常实际的问题 他建立在很实际的问题之上 不从程序员的角度去思考问题 则是从软件的角度去思考如何复用错综复杂的代码 因为 这个问题的本质是我们没有给底层的硬件一个完整的可按顺序执行的程序 我们在前几章虽然讨论了指令流的问题
  • 【Node.js实战】一文带你开发博客项目之Koa2重构(实现session、开发路由、联调、日志)

    个人简介 个人主页 前端杂货铺 学习方向 主攻前端方向 也会涉及到服务端 个人状态 在校大学生一枚 已拿多个前端 offer 秋招 未来打算 为中国的工业软件事业效力n年 推荐学习 前端面试宝典 Vue2 Vue3 Vue2 Vue3项目实
  • QT--SQLite

    QT数据库实例 QT Sqlite操作 转载于 http mobile 51cto com symbian 273444 htm 585532 tsina 1 51851 7e393678b940a4d55500bf3feae3d2e9 S
  • 时序分解

    时序分解 MATLAB实现基于LMD局部均值分解的信号分解分量可视化 目录 时序分解 MATLAB实现基于LMD局部均值分解的信号分解分量可视化 效果一览 基本介绍 程序设计 参考资料 效果一览 基本介绍 LMD局部均值分解 直接替换Exc
  • 思维模型:建立高品质思维的30种模型

    第一章 如何快速而全面地做出决策 思维模型1 关注 重要 任务 忽略 紧急 任务 用于区分真正的优先事项和冒牌货 重要任务和紧急任务区分开 把活动和需求分类 整理出最重要的任务 并找出为了实现这些重要任务需要采取哪些最关键的流程 重要任务
  • 游戏开发unity插件CRI ADX2系列:插件下载及教程

    推荐一个比较好的声音插件 可以在较大压缩音乐资源的同时维持较好的音质 教程 https blog criware cn category tutorials https www bilibili com video av56190616 C
  • 玩转Makefile

    1 前言 Makefile是一个神奇的东西 有了它只需一个make命令就可以让源文件按你的规则编译成你所想要的程序 非常简单 方便 对于Keil VS等IDE 一般只需点一下绿色的三角按钮 就可以完成编译 但具体内部是怎么实现编译的 改动文
  • 【Spark ML】第 1 章:机器学习简介

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore

随机推荐

  • 解决粒子特效被NGUI遮挡的问题。

    最近给UI添加粒子特效时 总是被UI遮挡 解决方法是 因为粒子系统的渲染顺序列默认为3000 而NGUI的渲染顺序默认也是从3000开始 当有嵌套的panel时或者Depth更高的panel时 GUI的渲染顺序会高于3000 解决办法是 1
  • ValueError: PyCapsule_GetPointer called with incorrect name

    ValueError PyCapsule GetPointer called with incorrect name解决问题的方式 增高pyqt5的版本 增高pyqt5的版本 我遇到了这个问题的时候在网上查的一直是说需要降低pyqt5的版本
  • 嵌入式开发linux控制鼠标,嵌入式系统/ARM技术中的linux中如何使用微软鼠标的第4、5键...

    虽说使用linux的人大都对微软没什么好感 但不能否认微软确实也出了不少好东西呀 比如微软鼠标 IE系列 icon smile gif IE 2 0和以上版本都有5个按钮 除了正常的左中右外 两侧还各有一个 在windows中可用来支持浏览
  • 面试题之你对redis的认识

    这里是我自己看书对redis的总结 这次我们目标的Redis在java互联网项目网中的作用 在传统的javaweb项目中 使用数据库进行存储数据 但是有一些致命的弊端 主要来自性能方面 由于数据库持久化数据主要是面向磁盘 而磁盘的读 写比较
  • yarn-container的理解

    不管是MR还是spark 分布式并行计算是肯定的 分布式计算意味着多节点 每个节点必须要并行跑很多task 任务 因为如果一个节点只有一个task 那么节点数量远远不够 让开发者直接操作 cpu和内存显然不合理 要用container抽象
  • 用户在输入不符合格式要求的内容或出现多个小数点时,无法继续输入新内容,但仍然可以使用后退键进行修正

  • 美国大学生数学建模竞赛赛题特点

    美国大学生数学建模竞赛赛题特点 赛题灵活度高 内容广泛 反恐 防灾 环境 健康医疗 交通 新能源等等 开放性大 评价类问题多且复杂 离散型优化问题多 除A题 如 2016B太空碎片的处理 2018D电动车充电桩的优化 2019D卢浮宫疏散路
  • 重要通知:9月1日起,微信小程序须完成备案后才可上架

    微信官方通知 近日 工信部发布了 工业和信息化部关于开展移动互联网应用程序备案工作的通知 8月9日 微信公众平台也发布了 关于开展微信小程序备案的通知 一 备案必要性 在中华人民共和国境内从事互联网信息服务的移动互联网应用程序主办者 应当依
  • ArduCopter调试

    1 ArduPilot main 我们知道 在 C语言中最经典的程序是 Hello World 这应该是我们在 C语言中最早接触的一个程序了 而在单片机中 最经典的一个程序当属 LED了 那么这里我们为什么不去分析 Hello World
  • 使用嵌入式linux完全手册光盘的arm-linux-gcc 遇到问题 自己编译

    Redhat9下重新生成交叉编译器gcc 3 4 5 glibc 2 3 6 看到论坛上有兄弟也遇到 arm linux gcc lib tls libc so 6 version GLIBC 2 4 not found required
  • 鸿蒙手机录音,录音应用的隐藏功能,90%的人不知道?

    录音应用的隐藏功能 90 的人不知道 2019 04 22 16 57 20 1点赞 0收藏 0评论 录音应用其实隐藏着可以自动开始和结束 脱离手用蓝牙耳机录音 只在说话时录音 你使用过吗 这款录音应用可是被苹果App Store推荐过的
  • 从零开始:在腾讯云轻量服务器上安装Docker,实现快速开发和部署!

    本文指导您如何在 零基础轻量应用服务器上安装 Docker 以及使用 Docker 镜像源加速镜像下载 好了 没有废话 让我们开始行动吧 第一步 购买服务器 小编买的是 腾讯的 1年446RMB 下载链接如下 学生云服务器 学生云主机 学生
  • 可靠数据传输的实现

    可靠数据传输协议 我们知道 TCP和UDP都是基于IP网际协议来传输数据的 但是IP网际协议是一种不可靠数据传输协议 它不负责数据丢失等情况 而TCP是一种可靠数据传输 因此我们需要来关注TCP是如何实现可靠数据传输的 经完全可靠信道的可靠
  • wxc-button使用

  • 怎么理解回流跟重绘?什么场景下会触发?

    目录 一 什么是回流 下面这些操作会导致回流 二 什么是重绘 下面这些操作会导致重绘 除此之外还有一些其他引起重绘行为 三 如何避免回流与重绘 减少回流与重绘的措施 一 什么是回流 当渲染树中部分或者全部元素的尺寸 结构或者属性发生变化时
  • 多编程语言代码生成神器 CodeGeeX,编码效率提升十倍!

    点击上方 芋道源码 选择 设为星标 管她前浪 还是后浪 能浪的浪 才是好浪 每天 10 33 更新文章 每天掉亿点点头发 源码精品专栏 原创 Java 2021 超神之路 很肝 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网
  • 物理端口UP 协议DOWN 的排错步骤

    端口的物理层Up 但是协议Down 可能的原因有很多种 一般而言 链路层协议从 初始化到Up 起来 都会经过一个协议的 协商 过程 这里所说的协商是广义上的协商 既包括链路层协议本身规定的参数 能力协商 也包括协议所规定的定期性的链路通达性
  • Drupal YAML 反序列化代码执行漏洞(CVE-2017-6920)

    事件背景 框架漏洞收集 老外的CMS框架 比较复杂 数据流向太长 调试需要消耗较多的时间 漏洞说明 1 漏洞原理 2017年6月21日 Drupal官方发布了一个编号为CVE 2017 6920 的漏洞 影响为Critical 这是Drup
  • maven 仓库配置 pom中repositories属性

    什么是Maven仓库 在不用Maven的时候 比如说以前我们用Ant构建项目 在项目目录下 往往会看到一个名为 lib的子目录 那里存放着各类第三方依赖jar文件 如log4j jar junit jar等等 每建立一个项目 你都需要建立这
  • python实现二叉树遍历

    使用python实现二叉树的四种遍历 前序 中序 后序和层次遍历 以遍历下图二叉树为例 1 树的构造 代码如下 coding utf 8 class Node object 节点类 def init self elem 1 lchild N