树(基础)

news/2025/1/18 21:00:30/文章来源:https://www.cnblogs.com/March7thDev/p/18678862

1 定义

1.1 树是什么

树是一种数据结构,因为形似倒着的树而得名.

1.2 树的定义

递归定义

1.2.1 有根树的定义

形象化的,如图1,有根树存在根节点这一定义,从根节点可以分出任意个分支,这任意个分支又可以继续细分,分出的节点称为“子节点”。


抽象化的,树也是\(N\)个节点和\(N-1\)条边的集合。


每条边都将某个节点连接至他的父亲,而除去根节点外的每个节点都有父亲,每个结点之间互不相交。

1.2.2 无根树的定义

形象化的,无根树就是有根树删去根节点后得到的东西


抽象化的,无根树也是树是\(N\)个节点和\(N-1\)条边的集合。


每条边都将某个节点连接至他的父亲,每个节点互不相交

图1 有根树

1.3 有关树的一些常用术语

森林:每个连通块都是树的图。按照定义,一棵树也是森林


叶节点:没有子节点的节点


父亲:一个节点上一层的点


祖先:一个点上层的每一个点


子节点:一个节点延伸出的下一个节点


深度:一个点到根节点的层数(边数)


高度:从叶节点到根节点的层数。


兄弟:同一个父节点的子节点互为兄弟


后代:一个点下层的每一个点是当前点的后代。


:一个节点的子树个数(其实这个概念应该放在前面,大家可以试着使用度来概括一些前期概念)


内部节点:根以外的分支节点


树的度:这棵树各节点中度的最大值


图2 数的术语

1.4 特殊树

:满足与任意节点相连的边不超过2条的树


二叉树:每个节点最多只有两个子节点的树。


完整二叉树:每个节点的子节点数量都为2没有


完全二叉树:只有最下面两层节点度数可以\(<2\),且最下面一层节点都位于该层最左边的位置上。


完美二叉树:所有叶节点深度相同,且所有节点都只有两个子节点!


注意!完美二叉树一定也是完全二叉树和完满二叉树,但完满二叉树不一定是完全二叉树和完美二叉树。





1.5 二叉树的一些性质

性质部分:

1.在二叉树的第\(i\)层上最多有\(2^{i-1}\)个节点

2.深度为\(k\)的二叉树最多有\(2^k-1\)个节点

3.对任意一棵二叉树,如果其叶节点数为\(n_0\),度为\(2\)的节点数为\(n_2\),则一定满足\(n_0=n_2+1\)

4.具有\(n\)个基点的完全二叉树的深度为\(floor(log_2n)+1\)

5.对于一棵\(n\)个节点的完全二叉树,对任意一个节点\(i\),有:


5.1 如果\(i=1\),则节点\(i\)为根,无父节点;

5.2 如果\(i>1\),则其父节点编号为\(i/2\)

5.3 如果\(2*i>n\),则节点\(i\)是叶节点,否则左孩子编号为\(2*i\)

5.4 如果\(2*i+1>n\),则节点\(i\)无右孩子,否则右孩子编号为\(2*1+1\)



证明部分:

用归纳法证明性质1.

\(i=1\)时,

2 树的储存

2.1 普通树的储存

2.1.1 顺序存储

1.父亲表示法(数组记录孩子的父亲为父亲)

int data[N];//存数据的
int father[N];//father[i]=j 表示i的父亲为j

2.孩子表示法(数组记录父亲的第任意个孩子为孩子)

int data[N];//不做过多解释
int son[N][M];//son[i][j]=k表示父亲i的第j个孩子为k

3.父亲孩子表示法(双向奔赴的爱)

int data[N];//不做过多解释
int father[N];//father[i]=j 表示i的父亲为j
int son[N][M];//son[i][j]=k表示父亲i的第j个孩子为k

4.孩子兄弟表示法(见故事)

int data[N];//不做过多解释
int firstson[N];//表示父亲的第一个孩子
int nxt[N];//nxt[i]=j表示i的下一个兄弟为j

这里我们老师给我们讲了个故事,说乾隆生了100多个孩子,这时候怎么记是不是自己孩子呢?就让哥哥记住自己弟弟,弟弟在记住自己弟弟,这就是孩子兄弟表示法。

2.1.2 链式存储

1.父亲表示法

struct node
{int data;// 节点存储的数据node *father// 指向父节点的指针
}tree[N];//树

2.孩子表示法

struct node
{int data;// 节点存储的数据node *son[M];//指向子节点的指针
}tree[N];

3.父亲孩子表示法

struct node
{int data;//数据node *father;//指向父亲node *son[M];//指向孩子
}tree[N];

4.孩子兄弟表示法

struct node
{int data;//数据node *firstson;//第一个儿子node *bro;//下一个兄弟
}tree[N];

2.2 二叉树的存储

1.顺序存储

int data[N];//数据域

2.链式存储

struct node
{int data;node *lc;//左孩子node *rc;//右孩子node(int d)//构造函数{data=d;// 初始化节点数据为传入的参数dlc=NULL;// 初始化左子节点指针为NULLrc=NULL;// 初始化右子节点指针为NULL}//另一种写法/*node(int d) : data(d), lc(NULL), rc(NULL){}*/
};
node *bt;//根节点指针

3.树的遍历

先序遍历,中序遍历,后序遍历

3.1 先序遍历

如图8,先序遍历类似\(DFS\),从根开始,然后是左子树,递归到最深层后返回,然后遍历右子树,最后回到根



void preoder(int f)
{cout<<data[f]<<" ";//首先在函数运行前输出是为了先从根节点开始if(lc[2*f]>0)//左子树preoder(2*f);if(rc[2*f+1]>0)//右子树preoder(2*f+1);
}

3.2 中序遍历

如图9,中序遍历在遍历完左子树后直接跳向根节点后遍历右子树



void inoder(int f)
{if(lc[f]>0)inoder(lc[f]);cout<<data[f]<<endl;//在遍历左子树时输出是为了先从左子树开始if(rc[f]>0)inoder(rc[f]);
}

3.3 后序遍历

如图10,后序遍历在遍历完左子树后直接跳向右子树叶子节点后向上遍历至根节点



void postoder(int f)
{if(lc[f]>0)postoder(lc[f])if(rc[f]>0)postoder(rc[f]);cout<<data[f]<<endl;//在遍历右子树时输出是为了从右子树开始
}

3.4 FAQ

肯定会有彭于晏有疑问,为什么他们的输出位置不同,决定了他们的遍历次数不同?

1.先序遍历 首先在函数运行前输出是为了先从根节点开始

2.中序遍历 在遍历左子树时输出是为了先从左子树开始

3.后序遍历 在遍历右子树时输出是为了从右子树开始

神不神奇?反正我觉得挺神奇

接下来需要完善的:

2.二叉树性质 证明

4.反推

5.BFS

6.Morris

呼~~ 用时7个多小时终于写完了!希望能帮到你喵~~

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

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

相关文章

Java五子棋源码联网版+Socket+Swing+大学生练手项目

前言 学Java的朋友们,福利来了,今天小编给大家带来了一款 Java五子棋源码联网版 源码,看图: 实现了服务端和客户端。是联网版游戏基础模型。环境 JDK1.8代码采用原生java类库编写,界面采用swing,完整源码获取地址: gitee.com/hadluo/java_game01.git整体代码结构服务器采…

Java源码:实现斗地主游戏+大学生练手项目

前言 学Java的朋友们,福利来了,今天小编给大家带来了一款 斗地主 源码,看图:视频演示效果 https://githubs.xyz/show/5.mp4 环境 JDK1.8代码采用原生java类库编写,界面采用swing,完整源码获取地址: gitee.com/hadluo/java_game01.git项目结构 代码十分简洁,只有简单的7个…

文件蜈蚣 后台偷跑流量

我已经好久没有打开这个软件了,期间重启了很多次,他有一个服务应该开机时就启动,后台偷跑流量 filec.exe文件。 因为我没什么什么上传流量也很大,最终定位到这个文件在偷跑了。

windows安装ffmpeg

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。 ffmpeg安装 打开 FFmpeg 官网,选择下载。 选择 Windows 平台,下面有两个链接,都是可以的,选择其一。 本文以点…

Java源码:坦克大战+swing界面+大学生练手项目

前言 学Java的朋友们,福利来了,今天小编给大家带来了一款 坦克大战 源码,看图: 演示视频 https://githubs.xyz/show/22.mp4 环境 JDK1.8 实现步骤代码采用原生java类库编写,界面采用swing,完整源码获取地址: gitee.com/hadluo/java_game01.git启动类 启动类是 TankCline…

免费下载CapCut海外版,解锁剪映VIP功能无广告

大家好,今天给大家带来一个超级实用的教程——剪映海外版 CapCut 下载:免费解锁剪映 VIP 功能的完整步骤!剪映是目前非常流行的视频编辑软件,它让我们的短视频创作变得更加简单和高效。不管是记录生活点滴、制作旅行回忆,还是做一些创意短视频,剪映都提供了非常强大的功能…

Java源码:植物大战僵尸 + 大学生练手项目

前言 学Java的朋友们,福利来了,今天小编给大家带来了一款 植物大战僵尸源码,看图:视频演示 https://githubs.xyz/show/175.mp4 环境 JDK1.8代码采用原生java类库编写,完整源码获取地址: gitee.com/hadluo/java_game01.git类继承UML图源码实现 我们先从main函数看起,继承了…

Linux搭建Slurm和pbs单机版

SlurmSlurm 是高性能计算集群的出色工作调度工具。此外,当你需要同时运行多个程序并将它们排成队列,同时确保计算机或服务器不超载时,它也是本地台式机或单台服务器上的重要工具。此外,在与其他用户共享服务器或需要通宵或连续数周运行多个工作时,它也非常有用!在这里,我…

Java游戏源码:天天酷跑+大学生学习源码

学习java朋友们,福利来了,今天小编给大家带来了一款天天酷跑源码。注意:此源码仅供学习使用!!视频演示 https://githubs.xyz/show/209.mp4 源码搭建和讲解 代码采用原生java类库编写, 利用java swing作为界面框架,完整源码获取地址: gitee.com/hadluo/java_game01.git 启…

2024春秋杯冬季赛day2writeup_cyi

2024春秋杯冬季赛day2 misc wp 解题过程 misc Weevils Whisper 操作内容: 筛选http流,一开始就把马上传了搜索可知这是weevely的webshell 这篇讲的很详细了 https://xz.aliyun.com/t/11246?time__1311=Cq0xRD0Q0QD%3DdGNeeeqk75YitmczLbD#toc-5 拿了这篇的解密脚本 https:/…

长期更新IntelliJ IDEA安装永久破解教程

IntelliJ IDEA版本亲测IntelliJ IDEA 2024.3.2 ✔ IntelliJ IDEA 2024.3.1 ✔ IntelliJ IDEA 2024.2.* ✔ 介绍 JetBrains是一家专注于创建智能开发工具的前沿软件公司, 旗下常用的软件有IntelliJ IDEA、PhpStorm、PyCharm、Rider、RubyMine、RustRover、WebStorm、Goland、CLi…

5k之力!!!

卡了不知道多少页...(