数据结构 | 二叉树的应用

目录

一、解析树

二、树的遍历


一、解析树

我们可以用解析树来表示现实世界中像句子或数学表达式这样的构造。

我们可以将((7+3)*(5-2))这样的数学表达式表示成解析树。这是完全括号表达式,乘法的优先级高于加法和减法,但因为有括号,所以在做乘法前必须先做括号内的加法和减法。树的层次性有助于理解整个表达式的计算次序。在计算顶层的乘法前,必须先计算子树中的加法和减法。

 构建解析树的第一步是将表达式字符串拆分成标记列表。需要考虑4种标记:左括号、右括号、运算符和操作数。我们知道,左括号代表新表达式的起点,所以应该创建一颗对应该表达式的新树。反之,遇到右括号则意味着到达该表达式的终点。我们也知道,操作数既是叶子节点,也是其运算符的子节点。此外,每个运算符都有左右子节点。

有了上述信息,便可以定义以下4条规则:

(1)如果当前标记是(,就为当前节点添加一个左子节点,并下沉至该子节点;

(2)如果当前标记在列表['+','-','/','*']种,就将当前节点的值设为当前标记对应的运算符;为当前节点添加一个右子节点,并下沉至该子节点;

(3)如果当前标记是数字,就将当前节点的值设为这个数并返回至父节点;

(4)如果当前标记是),就跳到当前节点的父节点。

追踪父节点的方法:在遍历这棵树时使用栈记录父节点。每当要下沉至当前节点的子节点时,先将当前节点压到栈中。当要返回当前节点的父节点时,就将父节点从栈中弹出来。

解析树构建器代码如下:

from pythonds.basic import Stack
from pythonds.trees import BinaryTreedef bulidParseTree(fpexp):fplist=fpexp.split()pStack=Stack()eTree=BinaryTree('')pStack.push(eTree)currentTree=eTreefor i in fplist:if i=='(':currentTree.insertLeft('')pStack.push(currentTree)currentTree=currentTree.getLeftChild()elif i not in '+-*/)':currentTree.setRootVal(eval(i))parent=pStack.pop()currentTree=parentelif i in '+-*/':currentTree.setRootVal(i)currentTree.insertRight('')pStack.push(currentTree)currentTree=currentTree.getRightChild()elif i ==')':currentTree=pStack.pop()else:raise ValueError("Unknown Operator: "+i)return eTree

计算二叉解析树的递归函数:

def evaluate(parseTree):opers={'+':operator.add,'-':operator.sub,'*':operator.mul,'/':operator.truediv}leftC=parseTree.getLeftChild()rightC=parseTree.getRightChild()if leftC and rightC:fn=opers[parseTree.getRootVal()]return fn(evaluate(leftC),evaluate(rightC))else:return parseTree.getRootVal()

二、树的遍历

我们将对所有节点的的访问称为“遍历”,共有3种遍历方式,分别为前序遍历、中序遍历和后序遍历

前序遍历:

在前序遍历中,先访问根节点,然后递归地前序遍历左子树,最后递归地前序遍历右子树。

中序遍历:

在中序遍历中,先递归地中序遍历左子树,然后访问根节点,最后递归地中序遍历右子树。

后序遍历:

在后序遍历中,先递归地后序遍历左子树,然后递归地后序遍历右子树,最后访问根节点。

遍历树的代码格外简洁,这主要是因为遍历是递归的。

将前序遍历算法实现为外部函数:

def preorder(tree):if tree:print(tree.getRootVal())preorder(tree.getLeftChild())preorder(tree.getRightChild())

将前序遍历算法实现为BinaryTree类的方法:

def preorder(self):print(self.key)if self.leftChild:self.left.preorder()if self.rightChild:self.right.preorder()

后序遍历函数:

def postorder(tree):if tree!=None:postorder(tree.getLeftChild())postorder(tree.getRightChild())print(tree.getRootVal())

后序求值函数:

def postordereval(tree):opers={'+':operator.add,'-':operator.sub,'*':operator.mul,'/':operator.truediv}res1=Noneres2=Noneif tree:res1=postordereval(tree.getLeftChild())res2=postordereval(tree.getRightChild())if res1 and res2:return opers[tree.getRootVal()](res1,res2)else:return tree.getRootVal()

中序遍历函数:

def inorder(tree):if tree!=None:inorder(tree.getLeftChild())print(tree.getRootVal())inorder(tree.getRightChild())

修改后的中序遍历函数,它能还原完全括号表达式:

def printexp(tree):sVal=""if tree:sVal='('+printexp(tree.getLeftChild())sVal=sVal+str(tree.getRootVal())sVal=sVal+printexp(tree.getRightChild())+')'return sVal

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/27208.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ffmpeg下载安装教程

ffmpeg官网下载地址https://ffmpeg.org/download.html 这里以windows为例,鼠标悬浮到windows图标上,再点击 Windows builds from gyan.dev 或者直接打开 https://www.gyan.dev/ffmpeg/builds/ 下载根据个人需要下载对应版本 解压下载的文件,并复制bin所在目录 新打开一个命令…

嵌入式面试3

1.线程与进程的区别和联系? 线程是否具有相同的堆栈? dll是否有独立的堆栈? 进程是死的,只是一些资源的集合,真正的程序执行都是线程来完成的,程序启动的时候操作系统就帮你创建了一个主线程。 每个线程有自己的堆栈。 DLL中有没有独立的…

P2340 [USACO03FALL] Cow Exhibition G

P2340 [USACO03FALL] Cow Exhibition G 很典型的背包问题。要求 IQ 与 EQ 和的最大值,并保证 IQ EQ 和均大于 0,易知 dp,IQ 和 EQ 均大于 0 的条件可先不管,最后在合法区间统计答案即可。 考虑如何求 IQ 与 EQ 和的最大值&#x…

基于YOLOv7开发构建MSTAR雷达影像目标检测系统

MSTAR(Moving and Stationary Target Acquisition and Recognition)数据集是一个基于合成孔径雷达(Synthetic Aperture Radar,SAR)图像的目标检测和识别数据集。它是针对目标检测、机器学习和模式识别算法的研究和评估…

前端面试题-高频考点

1 typeof类型判断 typeof 是否能正确判断类型? instanceof 能正确判断对象的原理是什么typeof 对于原始类型来说,除了 null 都可以显示正确的类型 typeof 1 // number typeof 1 // string typeof undefined // undefined typeof true // boolean typeo…

手把手写深度学习(20):搭建LLM大语言模型的敏感词过滤系统

前言:随着Llama 2、通义千问7B等越来越多的大语言模型开源,开发者们可以基于这些开源的模型搭建自己的对话系统、Agent等。但是因为我们的国情,需要开发者对这些模型进行一些特殊的“安全性”考虑,保证与用户的交互不会出现“有害信息”。这篇博客手把手教大家搭建一个大语…

Camunda 7.x 系列【6】Spring Boot 集成 Camunda 7.19

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 前言2. Camunda Platform Run3. Spring Boot 版本兼容性4. 集成 Spring Boot5. 启动项目…

【Vue3】动态组件

动态组件的基本使用 动态组件(Dynamic Components)是一种在 Vue 中根据条件或用户输入来动态渲染不同组件的技术。 在 Vue 中使用动态组件,可以使用 元素,并通过 is 特性绑定一个组件的名称或组件对象。通过在父组件中改变 is 特…

vue 图片base64转化

import html2canvas from ‘html2canvas’ html2canvas(canvasDom, options).then(canvas > { //此时的图片是base64格式的,我们将图片格式转换一下 let type ‘png’; let imgData canvas.toDataURL(type); // 照片格式处理 let _fixType function(type) { …

2023牛客暑期多校训练营4

Bobo String Construction 结论,字符串哈希 Election of the King 二分查找 Merge the squares! 递归模拟,辗转相除法 Quest-ce Que Cest? DP,前缀和优化 We are the Lights 思维,倒推 猜测是,把n个字符全填0或者1是最…

亿发江西中小型制造企业信息化建设解决方案,2023数字化转型升级

实体经济在经济中的重要性愈发凸显,江西省作为制造业强省,要实现制造业经济高质量发展,信息技术与制造业的深度汇合是不可或缺的关键路径。在这个制造业转型升级的浪潮中,中小企业成为了江西省制造业转型的焦点。让我们深入探讨一…

Redis 7.X Linux 环境安装

Redis 简介 作为一名开发人员,想必大家对Redis一定是耳熟能详,因此在此只做简单介绍。 Remote Dictionary Server(远程字典服务)是完全开源的,使用ANSIC语言编写遵守BSD协议,是一个高性能的Key-Value内存数据库,它提…

分布式 - 服务器Nginx:一小时入门系列之HTTP反向代理

文章目录 1. 正向代理和反向代理2. 配置代理服务3. proxy_pass 命令解析4. 设置代理请求headers 1. 正向代理和反向代理 正向代理是客户端通过代理服务器访问互联网资源的方式。在这种情况下,客户端向代理服务器发送请求,代理服务器再向互联网上的服务器…

抖音seo矩阵系统源代码开发搭建技术分享

抖音SEO矩阵系统是一个较为复杂的系统,其开发和搭建需要掌握一定的技术。以下是一些技术分享: 技术分享 抖音SEO矩阵系统的源代码可以使用JAVA、Python、PHP等多种语言进行开发。其中,JAVA语言的应用较为广泛,因为JAVA语言有良好…

软件架构师思维塑造

一、软件系统设计的六项原则 1、单一职责原则(Single Responsibility Principle) 2、开闭原则(Open Closed Principle) 3、里氏替换原则(Liskov Substitution Principle) 4、迪米特法则(Law of …

无涯教程-Lua - nested语句函数

Lua编程语言允许在另一个循环中使用一个循环。以下部分显示了一些示例来说明这一概念。 nested loops - 语法 Lua中嵌套for循环语句的语法如下- for init,max/min value, increment dofor init,max/min value, incrementdostatement(s)endstatement(s) end Lua编程语言中的…

IMV3.0

经历了两个版本,基础内容在前面,可以使用之前的基础环境: v1: https://blog.csdn.net/wtt234/article/details/132139454 v2: https://blog.csdn.net/wtt234/article/details/132144907 一、代码组织结构 二、代码 2.…

下载网络文件到本地

文章目录 目录 前言 操作步骤 1.引入 2.读取出文件内容 3.筛选出URL 4.下载表情包 总结 前言 这里记录一次用代码下载网络文件的过程,以获取抖音表情包为例。 一、操作步骤 1.引入 首先抖音有网页版,用浏览器就可以观看,用户评论发布表情在…

Webpack5 core-js和babel-loader区别和用法

文章目录 core-js是什么,有什么用?为什么使用了babel-loader对js进行兼容性配置还需要core-js?core-js的具体用法总结 core-js是什么,有什么用? core-js是一个流行的JavaScript库,它提供了对新的JavaScript特性、API…

Rookit系列一 【隐藏网络端口】【支持Win7 x32/x64 ~ Win10 x32/x64】

文章目录 Rookit系列一 【隐藏网络端口】【支持Win7 x32/x64 ~ Win10 x32/x64】前言探究隐藏网络端口netstat分析隐藏网络端口的原理关键数据结构隐藏网络端口源码 效果演示 Rookit系列一 【隐藏网络端口】【支持Win7 x32/x64 ~ Win10 x32/x64】 前言 Rookit是个老生常谈的话…