位置: 编程技术 - 正文

Python实现二叉搜索树(python二叉树)

编辑:rootadmin

推荐整理分享Python实现二叉搜索树(python二叉树),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:验证二叉搜索树 python,python 二叉树遍历,python二叉搜索树建立,python二叉树算法,python 二叉搜索树,判断二叉搜索树的算法python,python二叉树算法,python二叉排序树怎么构造,内容如对您有帮助,希望把文章链接给更多的朋友!

二叉搜索树

我们已经知道了在一个集合中获取键值对的两种不同的方法。回忆一下这些集合是如何实现ADT(抽象数据类型)MAP的。我们讨论两种ADT MAP的实现方式,基于列表的二分查找和哈希表。在这一节中,我们将要学习二叉搜索树,这是另一种键指向值的Map集合,在这种情况下我们不用考虑元素在树中的实际位置,但要知道使用二叉树来搜索更有效率。

搜索树操作

在我们研究这种实现方式之前,让我们回顾一下ADT MAP提供的接口。我们会注意到,这种接口和Python的字典非常相似。

Map() 创建了一个新的空Map集合。 put(key,val) 在Map中增加了一个新的键值对。如果这个键已经在这个Map中了,那么就用新的值来代替旧的值。 get(key) 提供一个键,返回Map中保存的数据,或者返回None。 del 使用del map[key]这条语句从Map中删除键值对。 len() 返回Map中保存的键值对的数目 in 如果所给的键在Map中,使用key in map这条语句返回True。

搜索树实现

一个二叉搜索树,如果具有左子树中的键值都小于父节点,而右子树中的键值都大于父节点的属性,我们将这种树称为BST搜索树。如之前所述的,当我们实现Map时,BST方法将引导我们实现这一点。图 1 展示了二叉搜索树的这一特性,显示的键没有关联任何的值。注意这种属性适用于每个父节点和子节点。所有在左子树的键值都小于根节点的键值,所有右子树的键值都大于根节点的键值。

图 1:一个简单的二叉搜索树

现在你知道什么是二叉搜索树了,我们再来看如何构造一个二叉搜索树,我们在搜索树中按图 1 显示的节点顺序插入这些键值,图 1 搜索树存在的节点:,,,,,,。因为 是第一个被插入到树的值,它是根节点。接下来, 小于 ,因此是 的左子树。接下来, 大于 ,因此是 的右子树。我们现在填充了该树的两层,所以下一个键值,将会是 或者 的左子树或右子树。由于 大于 和 ,就变成了 的右子树。同样, 小于 和 ,因此成为了 的左子树。 也小于 ,因此必须是 的左子树。然而,它大于 ,所以是 的右子树。

为了实现二叉搜索树,我们将使用节点和引用的方法,这类似于我们实现链表和表达式树的过程。因为我们必须能够创建和使用一个空的二叉搜索树,所以我们将使用两个类来实现,第一个类我们称之为 BinarySearchTree,第二个类我们称之为TreeNode。BinarySearchTree类有一个TreeNode类的引用作为二叉搜索树的根,在大多数情况下,外部类定义的外部方法只需检查树是否为空,如果在树上有节点,要求BinarySearchTree类中含有私有方法把根定义为参数。在这种情况下,如果树是空的或者我们想删除树的根,我们就必须采用特殊操作。BinarySearchTree类的构造函数以及一些其他函数的代码如Listing 1 所示。

Listing 1

TreeNode类提供了许多辅助函数,使得BinarySearchTree类的方法更容易实现过程。如Listing 2 所示,一个树节点的结构,是由这些辅助函数实现的。正如你看到的那样,这些辅助函数可以根据自己的位置来划分一个节点作为左或右孩子和该子节点的类型。TreeNode类非常清楚地跟踪了每个父节点的属性。当我们讨论删除操作的实现时,你将明白为什么这很重要。

对于Listing 2 中的TreeNode实现,另一个有趣的地方是,我们使用Python的可选参数。可选的参数很容易让我们在几种不同的情况下创建一个树节点,有时我们想创建一个新的树节点,即使我们已经有了父节点和子节点。与现有的父节点和子节点一样,我们可以通过父节点和子节点作为参数。有时我们也会创建一个包含键值对的树,我们不会传递父节点或子节点的任何参数。在这种情况下,我们将使用可选参数的默认值。

Listing 2

现在,我们拥有了BinarySearchTree和TreeNode类,是时候写一个put方法使我们能够建立二叉搜索树。put方法是BinarySearchTree类的一个方法。这个方法将检查这棵树是否已经有根。如果没有,我们将创建一个新的树节点并把它设置为树的根。如果已经有一个根节点,我们就调用它自己,进行递归,用辅助函数_put按下列算法来搜索树:

Python实现二叉搜索树(python二叉树)

从树的根节点开始,通过搜索二叉树来比较新的键值和当前节点的键值,如果新的键值小于当前节点,则搜索左子树。如果新的关键大于当前节点,则搜索右子树。

当搜索不到左(或右)子树,我们在树中所处的位置就是设置新节点的位置。向树中添加一个节点,创建一个新的TreeNode对象并在这个点的上一个节点中插入这个对象。

Listing 3 显示了在树中插入新节点的Python代码。_put函数要按照上述的步骤编写递归算法。注意,当一个新的子树插入时,当前节点(CurrentNode)作为父节点传递给新的树。

我们执行插入的一个重要问题是重复的键值不能被正确的处理,我们的树实现了键值的复制,它将在右子树创建一个与原来节点键值相同的新节点。这样做的后果是,新的节点将不会在搜索过程中被发现。我们用一个更好的方式来处理插入重复的键值,旧的值被新键关联的值替换。我们把这个错误的修复,作为练习留给你。

Listing 3

随着put方法的实现,我们可以很容易地通过__setitem__方法重载[]作为操作符来调用put方法(参见Listing 4)。这使我们能够编写像myZipTree['Plymouth'] = 一样的python语句,这看上去就像Python的字典。

Listing 4

图 2 说明了将新节点插入到一个二叉搜索树的过程。灰色节点显示了插入过程中遍历树节点顺序。

图 2: 插入一个键值 = 的节点

一旦树被构造,接下来的任务就是为一个给定的键值实现检索。get方法比put方法更容易因为它只需递归搜索树,直到发现不匹配的叶节点或找到一个匹配的键值。当找到一个匹配的键值后,就会返回节点中的值。

Listing 5 显示了get,_get和__getitem__的代码。用_get方法搜索的代码与put方法具有相同的选择左或右子树的逻辑。请注意,_get方法返回TreeNode中get的值,_get就可以作为一个灵活有效的方式,为BinarySearchTree的其他可能需要使用TreeNode里的数据的方法提供参数。

通过实现__getitem__方法,我们可以写一个看起来就像我们访问字典一样的Python语句,而事实上我们只是操作二叉搜索树,例如Z = myziptree ['fargo']。正如你所看到的,__getitem__方法都是在调用get。

Listing 5

使用get,我们可以通过写一个BinarySearchTree的__contains__方法来实现操作,__contains__方法简单地调用了get方法,如果它有返回值就返回True,如果它是None就返回False。如Listing 6 所示。

Listing 6

回顾一下__contains__重载的操作符,这允许我们写这样的语句:

Python实现二叉堆 优先队列的二叉堆实现在前面的章节里我们学习了先进先出(FIFO)的数据结构:队列(Queue)。队列有一种变体叫做优先队列(PriorityQueue)。优先队列

Python解析树及树的遍历 解析树完成树的实现之后,现在我们来看一个例子,告诉你怎么样利用树去解决一些实际问题。在这个章节,我们来研究解析树。解析树常常用于真实

Python内建数据结构详解 一、列表(List)list是一个可以在其中存储一系列项目的数据结构。list的项目之间需用逗号分开,并用一对中括号括将所有的项目括起来,以表明这是

标签: python二叉树

本文链接地址:https://www.jiuchutong.com/biancheng/382321.html 转载请保留说明!

上一篇:Python的组合模式与责任链模式编程示例(python组合运算)

下一篇:Python实现二叉堆(python 二叉堆)

  • 开普票需要交税多少
  • 餐饮业税务申报
  • 企业经营的范围怎么写
  • 会计核算是否健全 填错了有影响吗
  • 交易性金融资产公允价值变动计入
  • 建筑业工人工资保障
  • 代扣代缴个税返点怎么申请
  • 保险企业汇算清缴规定
  • 应交税费应交增值税减免税款
  • 新个税聘用退休后怎么算
  • 流动资产短期借款
  • 住房租金专项附加扣除申报方式
  • 资产减值损失确认后,减值资产的折旧
  • 出口转内销增值税报表怎么填
  • 仓库货物破损处理方法
  • 个人账户可以转公户吗?
  • 企业员工报销法律规定
  • 未报税会怎么样
  • 免税企业收到的专用发票要怎么转出
  • 物业公司怎么开发票
  • 无形资产入账价值包括注册费吗
  • 出口发票认证相符要多久
  • 商品进销差价如何结平
  • 企业缴纳印花税会计分录
  • 汇兑差额会计处理
  • 企业资产转移是什么意思
  • 物业公司收取电费加价依据
  • 物业公司哪些收费项目
  • 暂估入库有时间限制吗
  • 收到场地租赁费入什么科目
  • 投标保证金利息规定
  • 硬盘 安装系统
  • 培训机构开办资金
  • type3插件
  • iphone6splus 充电
  • 商品从总仓到分拣要多久
  • 用公司资质应交什么费用
  • 航天信息服务费发票哪里打印
  • ecap.exe是什么意思
  • 同业代付融资
  • yolov3数据集格式
  • 原材料按实际成本核算需设置的科目包括
  • php数组处理函数array_push会影响源数组的元素吗
  • 国税申报系统操作流程
  • 企业间借款利息开票税收分类编码
  • 营改增后房地产企业增值税如何核算
  • 开发成本为什么放在存货里
  • 同时运行多个MySQL服务器的方法
  • 季度利润表中的利润总额
  • 新准则下其他应收坏账
  • 应付账款暂估会计处理
  • 政府扶持资金的优缺点
  • 出口退税的会计处理
  • 企业录用失业人员补贴
  • 新产品的研发费用扣除例题
  • 集团公司对子公司总经理的绩效考核
  • 公司入账是什么意思
  • win10 怎么设置
  • Windows Server 2003下DHCP服务器的安装与简单配置图文教程
  • vmwareworkstation10虚拟机
  • winxp开机画面自动重启
  • win8装机教程
  • Omniserv.exe - Omniserv是什么进程 有什么用
  • win7怎么连接手机上网
  • win10网络共享失败
  • linux怎么cd
  • Tutorial 3: First Triangle
  • yarn和npm一起使用冲突
  • js仿QQ中对联系人向左滑动、滑出删除按钮的操作
  • Node.js中的核心模块包括哪些内容?
  • 提高你工作效率的方法
  • jquery获取自定义标签的值
  • javascript入门教学
  • 21个JavaScript事件(Events)属性汇总
  • jQuery.Uploadify插件实现带进度条的批量上传功能
  • 如何在电子税务局添加办税人员
  • 静海去天津的公交
  • 国家税务总局核定的该车最低计税价格
  • 新电子税务局使用方法
  • 丰田2.0和2.5混动发动机
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设