数据结构之二叉树 Python实现

2023-05-16

树是一种非线性的数据结构。树,它是若干结点的集合,是由唯一的根和若个棵互不相交的子树组成的。其中,每一棵子树又是一棵树,也是由唯一的根结点和若干棵互不相交的子树组成的。由此可知,树的定义是递归的,即在树的定义中又用到了树的定义。要注意的是,树的结点数目可以为0,当为0时,这棵树称为一棵空树,这是一种特殊情况。

在这里插入图片描述

树的基本术语

  • 结点:A、B、C等都是结点,结点不仅包含数据元素,而且包含指向子树的分支。例如,A结点不仅包含数据元素A,而且包含3个指向子树的指针。
  • 结点的度:结点拥有的子树个数或者分支的个数。例如,A结点有3棵子树,所以A结点的度为3。
  • 树的度:树中各结点度的最大值。如例子中结点度最大为3(A、D结点),最小为0(F、G、I、J 、K、L、M结点),所以树的度为3。
  • 叶子结点:又叫作终端结点,指度为0的结点,如F、G,I、J、K、L、M结点都是叶子结点
  • 非终端结点:又叫作分支结点,指度不为0的结点,如A、B、C、D、E,H结点都是非终端结点。除了根结点之外的非终端结点,也叫作内部结点,如B、C、D、E、H结点都是内部结点。
  • 孩子:结点的子树的根,如A结点的孩子为B、C、D。
  • 双亲:与孩子的定义对应,如B,C、D结点的双亲都是A
  • 兄弟:同一个双亲的孩子之间互为兄弟。如B、C、D互为兄弟,因为它们都是A结点的孩子。
  • 祖先:从根到某结点的路径上的所有结点,都是这个结点的祖先。如K的祖先是A,B,E,因为从A到K的路径为A-B-E-K。
  • 子孙:以某结点为根的子树中的所有结点,都是该结点的子孙。如D的子孙为H、I、J、M。
  • 层次:从根开始,根为第一层,根的孩子为第二层,根的孩子的孩子为第三层,以此类推。
  • 树的高度(或者深度),树中结点的最大层次——如例子中的树共有4层,所以高度为4。
  • 结点的深度和高度:
    1)结点的深度是从根结到该结点路径上的结点个数。
    2)从某结点往下走可能到达多个叶子结点,对应了多条通往这些叶子结点的路径,其中最长的那条路径的长度即为该结点在树中的高度,如结点D的高度为3、就是从D到M的路径长度
    3)根结点的高度为树的高度,如结点A,其高度为4,是从A到K(L,M)这条路径的长度,也是整棵树的高度。
  • 堂兄弟:双亲在同一层的结点互为堂兄弟。如G和H互为堂兄弟,因为G的双亲是C,H的双亲是D。C和D在同一层上,注意和兄弟的概念的区分。
  • 有序树:树中结点的子树从左到右是有次序的,不能交换,这样的树叫作有序树。
  • 无序树:树中结点的子树没有顺序,可以任意交换,这样的树叫作无序树。
  • 丰满树:丰满树即理想平衡树,要求除最底层外,其他层都是满的。
  • 森林:若干棵互丕相交的树的集合。例于中如果把根A去掉,剩下的3棵子树互不相交,它们组成一个森林。

树的存储结构

  • 顺序存储——适用于满二叉树或完全二叉树
  • 链式存储

树的性质

1)总结点数等于总分支数加1。
2) m m m叉树第i层上最多有 m i − 1 m^{i-1} mi1个结点 ( i ≥ 1 ) (i\geq1) i1
3)高为 h h h m m m叉树至多有 ( m h − 1 ) / ( m − 1 ) (m^{h}-1)/(m-1) (mh1)/(m1)个结点,即满 m m m叉树前 h h h层有 ( m h − 1 ) / ( m − 1 ) (m^{h}-1)/(m-1) (mh1)/(m1)个结点。
4)具有 n n n个结点“ m m m叉树最小高度”或“完全 m m m叉树的高度”为 ⌈ log ⁡ m [ n ( m − 1 ) + 1 ] ⌉ \lceil {\log_m{[n(m-1)+1]}}\rceil logm[n(m1)+1]

二叉树的定义

1)每个结点最多只有两个子树,即二叉树中结点的度只能为0,1,2。
2)子树有左右顺序之分,不能颠倒。
在这里插入图片描述

  • 满二叉树:在一棵二叉树中,如果所有的分支结点都有左孩子和右孩子结点,并且叶子结点都集中在二叉树的最下一层,则这样的二义树称为满二叉树。
  • 完全二叉树:对满二叉树进行编号,约定编号从1开始,从上到下,自左至右进行。如果对一个深度为k,有n个结点的二叉树进行编号后,各结点的编号与深度为k的满二叉树中相同位置上的结点的编号均相同,那么这棵二叉树就是一棵完全二叉树。

二叉树性质

1)总结点数等于总分支数加1。
2)二叉树第 i i i 层上最多有 2 i − 1 2^{i-1} 2i1个结点(i>=1)。
3)高为 h h h 的二叉树至多有 2 h − 1 2^{h}-1 2h1个结点,即满二叉树前 h h h 层有 2 h − 1 2^{h}-1 2h1个结点。
4)具有 n n n 个结点“二叉树最小高度”或“完全二叉树的高度”为 ⌈ log ⁡ 2 ( n + 1 ) ⌉ \lceil {\log_2{(n+1)}}\rceil log2(n+1)
5)有 n n n 个结点的完全二叉树,对各结点从上到下,从左到右依次编号为(1~n),则第 i i i 号结点:
父节点 ⌊ i / 2 ⌋ \lfloor i/2\rfloor i/2,左孩子 2 i 2i 2i,右孩子 2 i + 1 2i+1 2i+1,所在层次 ⌈ log ⁡ 2 ( i + 1 ) ⌉ \lceil {\log_2{(i+1)}}\rceil log2(i+1)
若从零开始编号,则第 i i i 号结点:父节点 ⌊ ( i − 1 ) / 2 ⌋ \lfloor (i-1)/2\rfloor (i1)/2,左孩子 2 i + 1 2i+1 2i+1,右孩子 2 i + 2 2i+2 2i+2,所在层次 ⌈ log ⁡ 2 ( i + 2 ) ⌉ \lceil {\log_2{(i+2)}}\rceil log2(i+2)

二叉树代码实现

二叉树节点结构定义

class TreeNode():
    def __init__(self,data,left=None,right=None):
        self.data = data
        self.left = left
        self.right = right

二叉树的插入(建立)

下面的代码以节点插入的方式,建立了一棵如图所示的二叉树
在这里插入图片描述

class TreeNode():
    def __init__(self,data,left=None,right=None):
        self.data = data
        self.left = left
        self.right = right

    def insertLeft(self,newNode):
        if self.left == None:
            self.left = TreeNode(newNode)
        else :
            return False

    def insertRight(self,newNode):
        if self.right == None:
            self.right = TreeNode(newNode)
        else :
            return False

    def moverightchild(self):
        return self.right

    def moveleftchild(self):
        return self.left

    def getRightchild(self):
        if self.right != None:
            return self.right.data
        else:
            return None

    def getLeftchild(self):
        if self.left != None:
            return self.left.data
        else:
            return None

    def getrootvalue(self):
        return self.data

r = TreeNode('a')
r.insertLeft('b')
r.insertRight('g')
k = r.moveleftchild()
k.insertLeft('c')
k.insertRight('d')
m = k.moverightchild()
m.insertLeft('e')
m.insertRight('f')
w = r.moverightchild()
w.insertLeft('h')

print(r.getrootvalue())
print(r.getLeftchild())
print(r.getRightchild())
print(k.getrootvalue())
print(k.getLeftchild())
print(k.getRightchild())
print(m.getrootvalue())
print(m.getLeftchild())
print(m.getRightchild())
print(w.getrootvalue())
print(w.getLeftchild())
print(w.getRightchild())

二叉树的遍历

先序遍历

递归方式:

def preOrderTravel(p):
    if p != None:
        print(p.data) #visit p
        preOrderTravel(p.left)
        preOrderTravel(p.right)

以上面建立的二叉树为例,先序遍历,查看结果

print("pre order is:")
preOrderTravel(r)
pre order is:
a
b
c
d
e
f
g
h

中序遍历

递归方式:

def inOrderTravel(p):
    if p != None:
        inOrderTravel(p.left)
        print(p.data)  # visit p
        inOrderTravel(p.right)

同样以上面建立的二叉树为例,中序遍历,查看结果

print("in order is:")
inOrderTravel(r)
in order is:
c
b
e
d
f
a
h
g

后序遍历

递归方式

def postOrderTravel(p):
    if p != None:
        postOrderTravel(p.left)
        postOrderTravel(p.right)
        print(p.data)  # visit p

同样以上面建立的二叉树为例,后序遍历,查看结果

print("post order is:")
postOrderTravel(r)
post order is:
c
e
f
d
b
h
g
a

层次遍历

def levelTravel(p):
    queue = []
    if p != None:
        queue.append(p)
        while queue:
            node = queue.pop(0)
            print(node.data)
            if node.left != None:
                queue.append(node.left)
            if node.right != None:
                queue.append(node.right)

同样以上面建立的二叉树为例,层次遍历,查看结果

print('level order is:')
levelTravel(r)
level order is:
a
b
g
c
d
h
e
f
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构之二叉树 Python实现 的相关文章

  • Python 中的 Lanczos 插值与 2D 图像

    我尝试重新缩放 2D 图像 灰度 图像大小为 256x256 所需输出为 224x224 像素值范围从 0 到 1300 我尝试了两种使用 Lanczos 插值来重新调整它们的方法 首先使用PIL图像 import numpy as np
  • 在 python 程序中合并第三方库的最佳实践是什么?

    下午好 我正在为我的工作编写一个中小型Python程序 该任务需要我使用 Excel 库xlwt and xlrd 以及一个用于查询 Oracle 数据库的库 称为CX Oracle 我正在通过版本控制系统 即CVS 开发该项目 我想知道围
  • OpenCV Python cv2.mixChannels()

    我试图将其从 C 转换为 Python 但它给出了不同的色调结果 In C Transform it to HSV cvtColor src hsv CV BGR2HSV Use only the Hue value hue create
  • Python(Selenium):如何通过登录重定向/组织登录登录网站

    我不是专业程序员 所以请原谅任何愚蠢的错误 我正在做一些研究 我正在尝试使用 Selenium 登录数据库来搜索大约 1000 个术语 我有两个问题 1 重定向到组织登录页面后如何使用 Selenium 登录 2 如何检索数据库 在我解决
  • 通过最小元素比较对 5 个元素进行排序

    我必须在 python 中使用元素之间的最小比较次数来建模对 5 个元素的列表进行排序的执行计划 除此之外 复杂性是无关紧要的 结果是一个对的列表 表示在另一时间对列表进行排序所需的比较 我知道有一种算法可以通过 7 次比较 总是在元素之间
  • Django:按钮链接

    我是一名 Django 新手用户 尝试创建一个按钮 单击该按钮会链接到我网站中的另一个页面 我尝试了一些不同的例子 但似乎没有一个对我有用 举个例子 为什么这不起作用
  • 如何使用 Ansible playbook 中的 service_facts 模块检查服务是否存在且未安装在服务器中?

    我用过service facts检查服务是否正在运行并启用 在某些服务器中 未安装特定的软件包 现在 我如何知道这个特定的软件包没有安装在该特定的服务器上service facts module 在 Ansible 剧本中 它显示以下错误
  • 使用 on_bad_lines 将 pandas.read_csv 中的无效行写入文件

    我有一个 CSV 文件 我正在使用 Python 来解析该文件 我发现文件中的某些行具有不同的列数 001 Snow Jon 19801201 002 Crom Jake 19920103 003 Wise Frank 19880303 l
  • 根据列值突出显示数据框中的行?

    假设我有这样的数据框 col1 col2 col3 col4 0 A A 1 pass 2 1 A A 2 pass 4 2 A A 1 fail 4 3 A A 1 fail 5 4 A A 1 pass 3 5 A A 2 fail 2
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • BeautifulSoup 中的嵌套标签 - Python

    我在网站和 stackoverflow 上查看了许多示例 但找不到解决我的问题的通用解决方案 我正在处理一个非常混乱的网站 我想抓取一些数据 标记看起来像这样 table tbody tr tr tr td td td table tr t
  • 添加不同形状的 numpy 数组

    我想添加两个不同形状的 numpy 数组 但不进行广播 而是将 缺失 值视为零 可能最简单的例子是 1 2 3 2 gt 3 2 3 or 1 2 3 2 1 gt 3 2 3 1 0 0 我事先不知道形状 我正在弄乱每个 np shape
  • 如何在ipywidget按钮中显示全文?

    我正在创建一个ipywidget带有一些文本的按钮 但按钮中未显示全文 我使用的代码如下 import ipywidgets as widgets from IPython display import display button wid
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • 如何在seaborn displot中使用hist_kws

    我想在同一图中用不同的颜色绘制直方图和 kde 线 我想为直方图设置绿色 为 kde 线设置蓝色 我设法弄清楚使用 line kws 来更改 kde 线条颜色 但 hist kws 不适用于显示 我尝试过使用 histplot 但我无法为
  • 为字典中的一个键附加多个值[重复]

    这个问题在这里已经有答案了 我是 python 新手 我有每年的年份和值列表 我想要做的是检查字典中是否已存在该年份 如果存在 则将该值附加到特定键的值列表中 例如 我有一个年份列表 并且每年都有一个值 2010 2 2009 4 1989
  • 解释 Python 中的数字范围

    在 Pylons Web 应用程序中 我需要获取一个字符串 例如 关于如何做到这一点有什么建议吗 我是 Python 新手 我还没有找到任何可以帮助解决此类问题的东西 该列表将是 1 2 3 45 46 48 49 50 51 77 使用
  • Scrapy:如何使用元在方法之间传递项目

    我是 scrapy 和 python 的新手 我试图将 parse quotes 中的项目 item author 传递给下一个解析方法 parse bio 我尝试了 request meta 和 response meta 方法 如 sc
  • Python Selenium:如何在文本文件中打印网站上的值?

    我正在尝试编写一个脚本 该脚本将从 tulsaspca org 网站获取以下 6 个值并将其打印在 txt 文件中 最终输出应该是 905 4896 7105 23194 1004 42000 放置的动物 的 HTML span class

随机推荐

  • 求职嵌入式软件开发linux kernel/BSP leader/工程师职位

    个人工作说明 xff1a 目前从事linux系统网络设备的开发工作 xff0c 负责bootloader linux kernel文件系统 xff0c driver移植 xff0c 以及开源app移植 主要技能和过去的经验 xff1a 1
  • 【2023最新】计算机网络面试题【收藏持续更新】

    你好 xff0c 我是萝卜 xff0c 我会在本篇文章持续更新关于计算机网络的面试题 最新内容更新日期 xff1a 2023 04 11 基础 说一下计算机网络体系结构 网络体系结构一般有三种 xff1a ISO七层模型 xff0c TCP
  • UDP协议详解

    概述 xff1a UDP只在IP的数据报服务之上增加了两个最基本的服务 xff1a 复用和分用以及差错检测 UDP不保证可靠交付 xff0c 但是不意味着应用对数据的要求是不可靠的 xff0c 只是所有维护可靠性的工作可由用户在应用层完成
  • TCP传输可靠性保证机制之重传机制

    TCP重传机制 tcp重传机制包括超时重传 快速重传 带选择确认的重传 SACK 重复SACK 四种 超时重传 xff1a 超时重传是tcp协议保证数据可靠性的一个重要机制 原理是在发送某一个数据以后开启一个计时器 xff0c 在一定时间内
  • VSCode:终端控制台常用指令

    常用的指令 以下是一些在 Visual Studio Code 终端控制台中常用的指令 xff1a 1 清除终端 xff1a clear 2 列出当前目录中的文件和文件夹 xff1a ls 3 切换到指定目录 xff1a xff1a cd
  • Ubuntu18.04安装ROS时rosdep update报错解决办法

    在安装ros进行rosdep update时经常会报错 xff0c 有时候可以通过换网解决 xff0c 但从我安装那么多次的经验来看 xff0c 仅有一次换手机热点后更新成功了 xff0c 其他都是失败 xff0c 成功率太低 从网上搜到了
  • 【STM32】STM32F103C8T6串口通信,实现3个串口收发数据

    串口通信 xff08 Serial Communications xff09 实现单片机与电脑或者其它外设进行通信 xff0c 通信时只需两根线 xff08 TX xff0c RX xff09 就可以实现数据传输 STM32f103有三个串
  • C语言学习笔记——(2)数组

    数组 1 什么是是数组2 数组的定义2 1数组的表达2 2数组的含义2 3数组的大小 xff1a 3 字符数组4 字符串操作5 二维数组 1 什么是是数组 数组是指有序的元素序列 如果将有限个类型相同的变量的集合命名 xff0c 那么这个名
  • 多线程编程实验

    xff08 一 xff09 查看下列程序并运行 xff0c 掌握如何通过扩展Thread类创建线程 span class token keyword package span span class token namespace case1
  • 实验一:基于Ubuntu系统实现无人机自主飞行

    ps xff1a 为避免出现错误 xff0c 在进行新的一步时 xff0c 需要关闭由于上一步操作打开的终端 xff0c 并开启一个新的终端 例如 xff1a 在开始第5步 安装MAVROS 之前 xff0c 关闭由于第3步 安装ROS 打
  • 5000字学习C语言错误处理的四种方式。

    C错误处理 在C语言中 xff0c 错误处理是一个非常重要的主题 通常情况下 xff0c 程序员需要在代码中处理错误 xff0c 以保证程序能够在出现错误时正确地处理这些情况 C语言中常见的错误类型包括 xff1a 语法错误 逻辑错误 运行
  • yum 源制作

    YUM介绍 YUM主要用于自动升级 安装 移除 rpm 软件包 xff0c 它能自动查找并解决 rpm 包之间的依赖关系 xff0c 要成功的使用 YUM 工具更新系统和软件 xff0c 需要有一个包含各种 rpm 软件包的 reposit
  • MATLAB021b与VS2022混编

    MATLAB2021b与VS2022混编 前言 目前在做一个大创项目 xff0c 其中用到关于Matlab与C的混合编程 xff0c 特此记录 Matlab2021b 如图所示 xff0c 红线划出的是即将使用的 c函数 xff0c 在左侧
  • 香橙派5使用NPU加速yolov5的实时视频推理(一)

    前言 xff1a 寒假里 xff0c 博主完成了树莓派4B搭载yolofastest V2的ncnn加速 xff0c 效果挺不错的 xff0c 但总感觉还是稍微差点意思 xff0c 于是就购买了一块香橙派5 xff0c 想要用RK3588芯
  • 香橙派5使用NPU加速yolov5的实时视频推理(二)

    三 将best onnx转为RKNN格式 这一步就需要我们进入到Ubuntu20 04系统中了 xff0c 我的Ubuntu系统中已经下载好了anaconda xff0c 使用anaconda的好处就是可以方便的安装一些库 xff0c 而且
  • 【STM32学习】——串口通信协议&STM32-USART外设&数据帧/输入数据策略/波特率发生器&串口发送/接受实操

    文章目录 前言一 串口通信1 通信接口2 串口通信 xff08 1 xff09 串口简介 xff08 2 xff09 串口硬件电路 xff08 3 xff09 串口软件部分 二 STM32的USART外设1 USART简介2 图示详解 三
  • 【STM32学习】——USART串口数据包&HEX/文本数据包&收发流程&串口收发HEX/文本数据包实操

    文章目录 前言一 数据包格式 xff08 江科大规定 xff09 1 HEX数据包2 文本数据包3 两者对比 二 数据包收发流程1 HEX数据包接收 xff08 只演示固定包长 xff09 2 文本数据包接收 xff08 只演示可变包长 x
  • buuctf simplerev 中的小头位序

    33条消息 BUUCTF SimpleRev xff08 涉及大小端序存储的问题 xff09 Ireb9z的博客 CSDN博客 buuctfsimplerev https blog csdn net afanzcf article deta
  • 简要分析网络编程——UDP编程

    计算机网络是指两台或更多的计算机组成的网络 xff0c 在同一个网络中 xff0c 任意两台计算机都可以直接通信 xff0c 因为所有计算机都需要遵循同一种网络协议 网络编程中有很多协议 xff0c 如 xff0c TCP协议 UDP协议
  • 数据结构之二叉树 Python实现

    树 树是一种非线性的数据结构 树 xff0c 它是若干结点的集合 xff0c 是由唯一的根和若个棵互不相交的子树组成的 其中 xff0c 每一棵子树又是一棵树 xff0c 也是由唯一的根结点和若干棵互不相交的子树组成的 由此可知 xff0c