[入门必看]数据结构5.2:二叉树的概念

[入门必看]数据结构5.2:二叉树的概念


第五章 树与二叉树

小题考频:30
大题考频:8


5.2 二叉树的概念

难度:☆☆☆

知识总览

5.2.1_1 二叉树的定义和基本术语

在这里插入图片描述

5.2.1_2 二叉树的性质

5.2.2 二叉树的存储结构

在这里插入图片描述


5.2.1_1 二叉树的定义和基本术语

在这里插入图片描述

二叉树的基本概念

二叉树是 n ( n ≥ 0 ) n(n≥0) n(n0)个结点的有限集合:
①或者为空二叉树,即n = 0。
②或者由一个根结点和两个互不相交的被称为根的左子树右子树组成。左子树和右子树又分别是一棵二叉树。

二叉树也是递归定义的数据结构
在这里插入图片描述

特点:
①每个结点至多只有两棵子树
②左右子树不能颠倒(二叉树是有序树

注意区别:度为2的有序树
度为2的有序树是指,在这个树里面至少会有一个结点,其有两个子树。


二叉树的五种状态

在这里插入图片描述


几个特殊的二叉树

满二叉树:

在这里插入图片描述
特点:
①只有最后一层有叶子结点
不存在度为1的结点
按层序从1开始编号,结点i的左孩子为2i右孩子为2i+1;结点i的父节点为[i/2] (如果有的话)【规律】

除了最下面一层叶子结点之外,所有的分支结点都长满了两个分支。
对于高度为h的满二叉树,第一层 2 0 2^0 20个,第二层 2 1 2^1 21个,第三层 2 2 2^2 22个……第h层有 2 h − 1 2^{h-1} 2h1个,对其求和可以算出高度为h的满二叉树有多少个结点。
 
对于有h层的满二叉树,每一层的节点数是上一层节点数的2倍。因此,第i层的节点数为2^(i-1)。将所有层的节点数相加即可得到该满二叉树的总节点数。
∑ i = 0 h − 1 2 i = 2 h − 1 \sum_{i=0}^{h-1}2^{i} = 2^{h} - 1 i=0h12i=2h1
因此,有h层的满二叉树共有 2 h − 1 2^h-1 2h1个节点。

完全二叉树:

完全二叉树:如果一棵树里的结点同样按照一层一层的方式编号,这些编号能够和满二叉树一一对应,那么这棵树就是完全二叉树:

可以这么理解,满二叉树每一层的结点都已经满了,不可能再有更多的结点。那么完全二叉树就是在满二叉树的基础上,将其某一些编号更大的结点给去掉。

在这里插入图片描述
特点:
特点:
①只有最后两层可能有叶子结点
最多只有一个度为1的结点
③按层序从1开始编号,结点i的左孩子为2i右孩子为2i+1;结点i的父节点为[i/2] (如果有的话)【规律同上】
④i ≤ [n/2] 为分支结点,i > [n/2] 为叶子结点【可取整】

如果去掉了中间的某个结点,那么编号就无法与满二叉树对应。
只有左边结果之后,才能继续往右边结。
完全二叉树中,如果某结点只有一个孩子,那么一定是左孩子。
在这里插入图片描述

二叉排序树:

二叉排序树:一棵二叉树或者是空二叉树,或者是具有如下性质的二叉树:
左子树上所有结点的关键字小于根结点的关键字;
右子树上所有结点的关键字大于根结点的关键字。
左子树和右子树又各是一棵二叉排序树。

在这里插入图片描述

左子树都小于根节点;
右子树都大于根节点

在这里插入图片描述

单独看左子树和右子树,其又是一颗二叉排序树。

基于这种特性,想要在二叉排序树上搜索某一个关键字就会变得很容易。

Eg1.如果想要找到60结点
60大于根节点的关键字19,往右子树找;
右子树根节点是50,小于60,继续往右子树找;
右子树根节点为66,大于60,往左子树找;
找到了关键字为60的结点,至此就完成了一个关键字的搜索。

Eg2.插入新结点68
68大于19,往右;
68大于50,往右;
68大于66,往右;
68小于70,同时已经到叶子结点,让结点68成为结点70的左孩子。
这样就保证了在插入一个新元素之后,这个树依然是二叉排序树。

二叉排序树可用于元素的排序、搜索

平衡二叉树:

平衡二叉树:树上任一结点的左子树和右子树的深度(高度)之差不超过1。

胖胖的、丰满的树

在这里插入图片描述

50的左子树的深度(高度)为2,右子树的深度(高度)为3,满足平衡二叉树的条件。
66的左子树的深度(高度)为1,右子树的深度(高度)为2,满足平衡二叉树的条件。
所有结点都满足。

再看一个例子:
在这里插入图片描述

根节点的左子树深度(高度)为1而右子树深度(高度)为6,其深度(高度)之差已经大于1,不是平衡二叉树。

尽可能追求左右子树的平衡,就可以得到更好的更高效的二叉排序树

给出的这两个例子其实都是二叉排序树,而且里面存的数据元素都是一样的。
如果要搜索关键字为70的结点,在平衡二叉树上往下走2步就可以找到;
在不平衡二叉树上要走很多很多步才能找到。
平衡二叉树能有更高的搜索效率
长得越胖越好,高度尽可能低,从根节点开始往下搜索时,因为高度低,所以搜索的次数就会减少。


5.2.1_2 二叉树的性质

二叉树的常考性质

常见考点1: n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1

常见考点1:设非空二叉树中度为0、1和2的结点个数分别为 n 0 n_0 n0 n 1 n_1 n1 n 2 n_2 n2 n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1(叶子结点比二分支结点多一个)

度为0的点(叶子结点)比度为2的点要多一个。

假设树中结点总数为n,因为二叉树里只可能有度为0,度为1和度为2这样三种结点,所以三种结点的数量加起来刚好是n
n = n 0 + n 1 + n 2 n = n_0 + n_1 + n_2 n=n0+n1+n2

树的结点个数等于总度数+1
因为对任何一种树来说,除了根节点之外,每一个结点的头上都会连一个分支,总度数就是这些分支的总数量,只有根节点头上是没有分支的,所以得出这样一个结论。
对于二叉树来说,度为1的结点有 n 1 n_1 n1个,度为2的结点有 n 2 n_2 n2个——其每个结点贡献2个度, n 1 + 2 n 2 n_1+2n_2 n1+2n2得到的就是总度数,总度数+1刚好是树的结点个数。
n = n 1 + 2 n 2 + 1 n=n_1+2n_2+1 n=n1+2n2+1

此处用②式-①式就可以得到这个结论:
n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1
 
十分重要

在这里插入图片描述


常见考点2:二叉树和m叉树第i层至多有多少结点

二叉树第i层至多有 2 i − 1 2^{i-1} 2i1个结点(i≥1)
m叉树第i层至多有 m i − 1 m^{i-1} mi1个结点(i≥1)


常见考点3:高度为h的二叉树和m叉树至多有多少结点

高度为h的二叉树至多有2ℎ − 1个结点(满二叉树)
高度为h的m叉树至多有 m h − 1 m − 1 \frac{m^h-1}{m-1} m1mh1个结点
(等比数列求和)


完全二叉树的常考性质

常见考点1:具有n个(n > 0)结点的完全二叉树的高度h为 ⌈ log ⁡ 2 ( n + 1 ) ⌉ \lceil \log _2\left( n+1 \right) \rceil log2(n+1) ⌈ log ⁡ 2 n ⌉ + 1 \lceil \log _2n \rceil +1 log2n+1

具有n个(n > 0)结点的完全二叉树的高度h为 ⌈ log ⁡ 2 ( n + 1 ) ⌉ \lceil \log _2\left( n+1 \right) \rceil log2(n+1) ⌈ log ⁡ 2 n ⌉ + 1 \lceil \log _2n \rceil +1 log2n+1

在这里插入图片描述

n的上下限,取对数

高为h的完全二叉树至少 2 h − 1 − 1 2^{h-1} − 1 2h11 个结点,至多 2 h − 1 2^ℎ − 1 2h1个结点

高为h的完全二叉树至少可以比高为h-1的满二叉树多1个结点

在这里插入图片描述

可以得到:第i个结点所在层次为 ⌈ log ⁡ 2 ( i + 1 ) ⌉ \lceil \log _2\left( i+1 \right) \rceil log2(i+1) ⌈ log ⁡ 2 i ⌉ + 1 \lceil \log _2i \rceil +1 log2i+1


常见考点2:对于完全二叉树,可以由的结点数n推出度为0、1和2的结点个数为 n 0 n_0 n0 n 1 n_1 n1 n 2 n_2 n2

在这里插入图片描述

完全二叉树只可能有一个度为一的结点
n 0 n_0 n0为叶子结点, n 2 n_2 n2为两分支结点,所以 n 0 + n 2 n_0+n_2 n0+n2 = 2 n 2 + 1 2n_2+1 2n2+1一定为奇数。

可以得到:

如果一个二叉树有偶数个结点的话,这就意味着 n 0 + n 1 + n 2 n_0+n_1+n_2 n0+n1+n2是一个偶数 2 k 2k 2k,由于 n 0 + n 2 n_0+n_2 n0+n2一定是一个奇数,那么 n 1 n_1 n1的值就是1,得到 n 0 = k n_0 = k n0=k n 2 = k − 1 n_2=k-1 n2=k1

如果一个二叉树有奇数个结点的话,这就意味着 n 0 + n 1 + n 2 n_0+n_1+n_2 n0+n1+n2是一个奇数 2 k − 1 2k-1 2k1,由于 n 0 + n 2 n_0+n_2 n0+n2一定是一个奇数,那么 n 1 n_1 n1的值就是0,得到 n 0 = k n_0 = k n0=k n 2 = k − 1 n_2=k-1 n2=k1


5.2.2 二叉树的存储结构

二叉树的顺序存储

在这里插入图片描述

一个 TreeNode就对应树中一个结点
每一个结点里包含一个ElemType,即实际要存的数据元素。
通过bool型变量来判断是否为空结点。

在这里插入图片描述

初始化数组时,需要把所有元素的isEmpty都设置为true,表示所有数据都是空的,没有存数据。

让t[0]位置空缺,因为完全二叉树的结点编号是从1开始的,从t[1]开始存储,那么数组的下标就刚好反映出完全二叉树里的结点编号。

由于数组是静态数组,长度是有限的,那么完全二叉树可以包含的结点数量也是有限的。

在这里插入图片描述

如果不是完全二叉树,也按照层序将各结点顺序存储:
在这里插入图片描述
在这里插入图片描述

但是我们,把二叉树的结点编号与完全二叉树对应起来,那么也可以反映出逻辑关系。

在这里插入图片描述

但无法判断结点的左右孩子,只能通过isEmpty来判断。
如果isEmpty为true,则说明该位置为空结点。

在这里插入图片描述

使用顺序存储来存储二叉树,里面会有大量空间是闲置的,这样会浪费大量空间。
最坏情况:所有的结点都只有右分支;
那么对于这个高度为h的二叉树,也至少需要 2 h − 1 2^h-1 2h1个存储单元。即高度为h的满二叉树的存储空间。

结论:二叉树的顺序存储结构,只适合存储完全二叉树。


二叉树的链式存储

二叉链表:
在这里插入图片描述

每一个结点都有一个data域用来存放实际的数据元素;
然后还有两个指针,分别指向其左孩子和右孩子;
如果一个结点没有孩子,就把对应的指针设为NULL
由于每个结点都有两个指针域,那么n个结点就有2n个指针域;
除了根节点,其他n-1个结点都连有一个指针,那么其他 n + 1 n+1 n+1个指针指向空,可以利用起来构造线索二叉树

定义结构体:
在这里插入图片描述

定义一颗空树,声明一个指向根节点的指针,初始值为NULL:
在这里插入图片描述
在这里插入图片描述

此时是一个空树

插入根结点,用malloc函数申请一个根结点:
在这里插入图片描述

此时这里在根结点中存入数字1;
并且让根结点的左右指针此时指向NULL

插入新结点,用malloc函数申请一个新结点:
在这里插入图片描述

在该结点中存入2;
把根结点的左孩子指针指向当前结点p
那么利用相同方法可以插入其他结点

在这里插入图片描述

  • 在二叉链表中,找到指定结点p的左/右孩子非常简单

只需要检查该结点的左孩子指针和右孩子指针指向哪里即可。

  • 在二叉链表中,找到指定结点p的父结点需要从根节点开始遍历寻找!

如果数据很多时,通过遍历的方法找某一结点的父结点就会很耗时。

如果在应用场景中,经常需要逆向查找某一结点的父节点
那么可以在该结构体中再定义一个指针,指向其父结点。
在这里插入图片描述

这样的实现方式称为:三叉链表——方便找父结点

下一节中,将介绍如何遍历二叉树的各个结点。


知识回顾与重要考点

5.2.1_1 二叉树的定义和基本术语

在这里插入图片描述

  • 满二叉树
  • 完全二叉树

5.2.1_2 二叉树的性质

在这里插入图片描述


5.2.2 二叉树的存储结构

顺序存储

在这里插入图片描述

  • 顺序存储二叉树,一定要把二叉树的结点编号和完全二叉树一一对应起来。
    ——这样才能通过结点编号来确定各个结点之间的关系。

  • 上文中的探讨,结点都是从1开始。
    ——思考:如果结点从0开始编号,如何找到结点i的左孩子、右孩子和父结点。

链式存储

在这里插入图片描述

  • n个结点的二叉链表共有n+1个空链域

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Navicat安装教程和评测

Navicat是一款功能强大的数据库管理软件,拥有丰富的功能和易于使用的界面,因此价格相对较高。此外,Navicat还提供了多种数据库类型的支持,包括MySQL、Oracle、PostgreSQL等,每种数据库类型都需要花费开发人员大量的时间…

飞利浦水健康携净水新品重磅亮相AWE2023

2023年度中国家电及消费电子博览会(AWE2023)于4月27日在上海新国际博览中心正式开幕。其中,飞利浦水健康携全屋高阶净水G5系列、厨下净水器U22Pro、冰热矿净四合一台式净饮机等新品悉数亮相,在暌违2年的AWE舞台上,为行…

小程序按钮重复点击解决方案

文章目录 前言一、为什么会发生重复点击二、针对以上问题怎么处理1、分析解决方法:1. 反馈2.禁用 三、最优解决总结 前言 小程序是直面用户便捷的应用,而在用户使用时往往都会涉及到关键节点的按钮点击,例如,注册登录时&#xff…

【技术】《Netty》从零开始学netty源码(四十八)之缓存池ObjectPool

目录 ObjectPool创建对象池获取对象get()从本地池中获取对象claim()回收对象 ObjectPool 在分析PooledByteBuf的时候我们遇到了recycleHandler类,该类用于回收已经使用完毕的缓存对象并将其放回池中供下次循环利用,Netty的对象池工作过程大体如下&#…

vulnhub靶机Misdirection

环境准备 下载链接:https://download.vulnhub.com/misdirection/Misdirection.zip 解压后双击ovf文件导入虚拟机 网络:DHCP、NAT、192.168.100.0/24网段 信息收集 主机发现 192.168.100.133是新增的ip 端口扫描 发现开放了以上端口,继续…

ChatGPT之父:未训练GPT-5

GPT等大型语言模型带动的芯片需求飙升趋势依然没有平息的迹象,英伟达的最新版旗舰AI芯片H100近日在网上的售价已经被炒到4万多美金,反映了科技行业对训练和部署人工智能软件的需求仍未被满足。 一、商业圈 1.马斯克成立新AI公司硬刚OpenAI 当地时间4月…

c++ 11标准模板(STL) std::vector (二)

定义于头文件 <vector> template< class T, class Allocator std::allocator<T> > class vector;(1)namespace pmr { template <class T> using vector std::vector<T, std::pmr::polymorphic_allocator<T>>; }(2)(C17…

如何使用递归函数实现Excel列号转换列标

在Excel中&#xff0c;列标与列号转换是VBA开发过程中经常用到的功能&#xff0c;下面这篇博客为大家解释了多种方法。 【Excel列标与列号转换】 那么这篇博文的核心是“递归过程”&#xff0c;实现这个功能并不是必须使用递归过程&#xff0c;但是这也不失为一种实现方法&am…

JavaScript实现输入圆的半径,输出周长、体积和面积的代码

以下为输入圆的半径,输出周长、体积和面积实现结果的代码和运行截图 目录 前言 一、请输入圆的半径,输出周长、体积和面积 1.1运行流程及思想 1.2代码段 1.3 JavaScript语句代码 1.4运行截图 前言 1.若有选择&#xff0c;您可以在目录里进行快速查找&#xff1b; 2.本博…

03 KVM虚拟机镜像制作

文章目录 03 KVM虚拟机镜像制作3.1 概述3.2 制作镜像3.2.1 使用root用户安装qemu-img软件包3.2.2 使用qemu-img工具的创建镜像文件 3.3 修改镜像磁盘空间大小3.3.1 查询当前虚拟机镜像磁盘空间大小3.3.2 修改镜像磁盘空间大小3.3.3 查询修改后的镜像磁盘空间大小 03 KVM虚拟机镜…

【HTML 标签详解】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f9be;&#x1f9be;&#x1f9be; 目录 1. HTML结构 1.1 HTML 基本结构 1.2 标签层…

DBeaver 没有菜单项 生成SQL Generate SQL

文章目录 Intro问题的根本有无该菜单项取决于你的查询SQL是单表还是多表&#xff1f;单表查询的结果集的菜单多表关联查询的结果集的菜单 测试版本 Intro DBeaver 是一款很棒的多平台、支持多数据源的GUI数据库客户端。 有一个我经常使用的功能就是&#xff1a; 当我查询到一个…

Linux内核阅读自学精简教程目录(必读)

学习Linux内核需要一定的计算机基础知识&#xff0c;包括操作系统&#xff0c;计算机网络等。 以下是学习Linux内核的步骤&#xff1a; 了解Linux内核的基本概念和架构&#xff0c;学习Linux内核源代码的组成和结构。学习C语言和汇编语言&#xff0c;这是深入理解Linux内核的…

界面控件DevExpress WinForm的垂直网格,让数据展示更灵活(二)

DevExpress WinForm Vertical Grid&#xff08;垂直网格&#xff09;组件设计用于提供UI灵活性&#xff0c;它允许显示数据集中的单个行&#xff0c;或在其90度反向网格容器中显示多个数据集行。此外&#xff0c;开发者还可以将其用作属性网格&#xff0c;就像在Visual Studio …

Python使用pytorch深度学习框架构造Transformer神经网络模型预测红酒分类例子

1、红酒数据介绍 经典的红酒分类数据集是指UCI机器学习库中的Wine数据集。该数据集包含178个样本&#xff0c;每个样本有13个特征&#xff0c;可以用于分类任务。 具体每个字段的含义如下&#xff1a; alcohol&#xff1a;酒精含量百分比 malic_acid&#xff1a;苹果酸含量&a…

用手机APP操作使用井用采样器更省时省力

井用采样器的主要功能特点就是&#xff1a;机身小巧&#xff0c;方便操作。可用于井下作业&#xff0c;手机APP可实时查看采样数据&#xff0c;节省人力。 利用自动采样器进行水样采集可以说节省很大的人力物力&#xff0c;但是有时为了采到更具代表性的水样&#xff0c;我们需…

JAVA-6-[Spring框架]Bean的作用域和生命周期

1 Spring Bean 1、Spring有两种类型bean&#xff0c;一种普通bean&#xff0c;另外一种工厂bean(FactoryBean)。 2、普通bean&#xff1a;在配置文件中定义的bean类型就是返回的类型。 3、工厂bean&#xff1a;在配置文件中定义的bean类型可以和返回类型不一样。 第一步 创建类…

React超级简单易懂全面的有关问题回答(面试)

目录 React事件机制&#xff1a; 2、React的事件和普通的HTML有什么不同&#xff1a; - 事件命名的规则不同&#xff0c;原生事件采用全小写&#xff0c;react事件采用小驼峰 3、React组件中怎么做事件代理&#xff1f;他的原理是什么&#xff1f; 4、React高阶组件、Rend…

mysql 如何避免索引失效

案例演示 建表及初始化数据 CREATE TABLE staffs (id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(24) NOT NULL DEFAULT ,age INT NOT NULL DEFAULT 0,pos VARCHAR(20) NOT NULL DEFAULT ,#职位add_time TIMESTAMP NOT NULL DEFAULT CURREN…

【源码解析】SpringBoot日志系统源码分析

LoggingApplicationListener 日志组件的处理是LoggingApplicationListener实现的。LoggingApplicationListener#onApplicationEvent&#xff0c;监听事件。如果实现接口GenericApplicationListener&#xff0c;可以允许适配事件类型。 private static final Class<?>[]…
最新文章