二叉树及其相关例题

目录

1.树

1.树的基本概念

2.结点之间的的关系描述(还是看上面的图)

3.结点之间的属性描述

4.有序树和无序树

5.森林

6.遍历顺序

1.前序遍历:从根结点——>根结点左子树——>根结点的右子树(中    左    右)

2.中序遍历:左子树——>根——>右子树(左    中    右)

3.后序遍历:左子树——>右子树——>根(左    右    中)

4.层序遍历:一层一层的去遍历

2.二叉树

1.二叉树的种类

(1)满二叉树:满二叉树的任意节点,要么度为0,要么度为2.换个说法即要么为叶子结点,要么同时具有                      左右分支

(2)完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1至h-1) 的结点数都达到最大个                              数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

(3)二叉搜索树:设立结点便于搜索,结点具有一定顺序,搜索一个结点的时间复杂度为O(log n)                             级别

(4)平衡二叉搜索树:左子树和右子树的高度差的绝对值并不能大于1,其实上图也是一个平衡二叉                                    搜索树

2.二叉树的存储方式

1.链式存储:用指针去指向下一个结点(这种情况用的最多)

2.线式存储:用一个数组来保存二叉树,用一个字符数组来保存二叉树,下标可以去代替指针

3.二叉树的遍历顺序

1.深度优先搜索(递归法和非递归法:迭代,都可以处理)

2.广度优先搜索:

3.总结

4.相关例题

第一题:美国血统

第二题:新二叉树

5.寄语:(写给每一个正在低谷期努力的人)


1.树

1.树的基本概念

树是有n个结点的有限集(一种递归定义的数据结构)

当n=0时,说明这个树是一个空树

当树不是空树时,有以下特征

1.有且只有一个根节点

2.没有后继的结点是叶子结点(终端结点)

3.有后继的结点(除了根结点)都称之为分支结点(非终端结点)

4.除了根结点外,其余结点都有且仅有一个前驱

5.每个结点都有0个或者多个后继

子树的概念:子树的概念是相对于某一个结点而言的,子树也是树。

比如说,B延伸所形成的树就是A的子树,E延伸所形成的树,就是B的子树,所以说,子树没有绝对的概念,只不过是相对的

树的图解

2.结点之间的的关系描述(还是看上面的图)

1.祖先结点:相对于E来说上面的B,A都是祖先结点

2.父亲结点:即B,就是其上一个结点

3.孩子结点:即K,L指自己延伸出去的结点

4.兄弟结点;即F,指的是和自己来自于同一个结点的结点

5.堂兄弟结点:一般是GHIJ,有可能会将F加入进来

6.什么是两个结点之间的路径:从上面的结点到下面的结点的路径

7.什么是路径长度:就是判断经过了几条边

3.结点之间的属性描述

1.结点的层次(深度):(默认从1开始,但是有可能也是0)从上往下数:如图所示

2.结点的高度从下往上数;和深度相反,KML是高度为1,到A是高度为4

3.树的高度:总共几层;这里就是4

4.结点的度:有几个分支,比如说A的度就是3,B的度为2;

5.树的度:各结点度的最大值。比如说在下图就是3,各结点最大分支数就是3;’

4.有序树和无序树

有序树——从逻辑上看,树中的结点的各子树从左到右都是有次序的(有逻辑顺序),不能交换

比如说家谱的记录,在同一层,都是按出生先后来记录的,不能改变顺序

无序树——从逻辑上看,树中结点的各子树从左到右都是无次序的,可以交换

比如说中国行政区的列举,你先列举河北还是先列举山东,都是一样的无伤大雅,可以去改变顺序

所以说,一棵树到底是有序树还是无序树,主要看的就是这棵树存的是什么,是否结点的左右位置会反映某些逻辑关系

5.森林

森林是m棵互不相交的树的集合;

森林连上同一个根结点就是一棵树,当然了,允许有空树也就允许有空森林,当m=0的时候,这个森林就是一个空森林

6.遍历顺序

(因为二叉树的考频更高,所以这里的遍历顺序是以二叉树为模版的)

这里说的前,中,后序遍历其实底层逻辑就是递归,通过递归的方式遍历这棵树,这三种遍历方式都属于dfs(深度优先搜索),不了解的可以看这篇博客:第一周算法训练之深度优先搜索

1.前序遍历:从根结点——>根结点左子树——>根结点的右子树(中    左    右)
void qian(shu* root)//前序遍历
{if (root == NULL){return;}printf("%d ", root->data);qian(root->left);qian(root->right);
}
2.中序遍历:左子树——>根——>右子树(左    中    右)
void zhong(shu* root)//中序遍历
{if (root == NULL){return;}zhong(root->left);printf("%d ", root->data);zhong(root->right);
}
3.后序遍历:左子树——>右子树——>根(左    右    中)
void hou(shu* root)//后序遍历
{if (root == NULL){return;}hou(root->left);hou(root->right);printf("%d ", root->data);
}

总和代码:

#include<stdio.h>
#include<stdlib.h>typedef struct tree//创建树的结构体
{int data;//树的代表的元素struct tree* left;//左指针struct tree* right;//右指针
} shu;// 新建结点
shu* jie(int x)
{shu* node = (shu*)malloc(sizeof(shu));node->data = x;node->left = NULL;node->right = NULL;return node;
}// 创建一个二叉树,返回根结点指针
shu* chuang()
{shu* node1 = jie(1);shu* node2 = jie(2);shu* node3 = jie(3);shu* node4 = jie(4);shu* node5 = jie(5);shu* node6 = jie(6);// 构建二叉树的关系node1->left = node2;node1->right = node4;node2->left = node3;node4->left = node5;node4->right = node6;return node1;
}// 前序遍历二叉树
void qian(shu* root)
{if (root == NULL){return;}printf("%d ", root->data);qian(root->left);qian(root->right);
}// 中序遍历二叉树
void zhong(shu* root)
{if (root == NULL){return;}zhong(root->left);printf("%d ", root->data);zhong(root->right);
}// 后序遍历二叉树
void hou(shu* root)
{if (root == NULL){return;}hou(root->left);hou(root->right);printf("%d ", root->data);
}int main()
{shu* root = chuang();qian(root); // 前序遍历printf("\n");zhong(root); // 中序遍历printf("\n");hou(root); // 后序遍历printf("\n");return 0;
}

运行结果:

4.层序遍历:一层一层的去遍历

其实这种遍历方式就相当于bfs广度优先搜索,是需要依靠队列来实现的一种算法 

void ceng(shu* root)//层序遍历
{Queue q; // 创建一个队列QueueInit(&q); // 初始化队列if (root) // 如果根节点存在QueuePush(&q, root); // 将根节点入队while (!QueueEmpty(&q)) // 当队列不为空时{shu* front = QueueFront(&q); // 获取队列的第一个元素(即树的结点)QueuePop(&q); // 将队列的第一个元素出队printf("%d ", front->data); // 打印出队的结点的数据if (front->left) // 如果左子节点存在QueuePush(&q, front->left); // 将左子节点入队if (front->right) // 如果右子节点存在QueuePush(&q, front->right); // 将右子节点入队}QueueDestory(&q); // 销毁队列
}

2.二叉树

1.二叉树的种类

(1)满二叉树:满二叉树的任意节点,要么度为0,要么度为2.换个说法即要么为叶子结点,要么同时具有                      左右分支

以下两个都是满二叉树

(2)完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1至h-1) 的结点数都达到最大个                              数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

(通俗来说就是除了底层以外,其它层都是满的(且从左到右需要连续)(这里主要看的就是p2与p3))

(3)二叉搜索树:设立结点便于搜索,结点具有一定顺序,搜索一个结点的时间复杂度为O(log n)                             级别

(左子树的所有结点都小于根节点,右子树的所有结点都大于根结点)

(4)平衡二叉搜索树:左子树和右子树的高度差的绝对值并不能大于1,其实上图也是一个平衡二叉                                    搜索树

2.二叉树的存储方式

1.链式存储:用指针去指向下一个结点(这种情况用的最多)

typedef struct tree//创建树的结构体
{int data;//树的代表的元素struct tree* left;//左指针struct tree* right;//右指针
} shu;

2.线式存储:用一个数组来保存二叉树,用一个字符数组来保存二叉树,下标可以去代替指针

假设数组第i个元素,2*i+1,代表左指针,2*i+2代表右指针。

ps:这种做法会非常局限一般不会用到。因为只适用于满二叉树,这就会让我们很被动,所以就不详细介绍了

3.二叉树的遍历顺序

1.深度优先搜索(递归法和非递归法:迭代,都可以处理)

包括前序遍历,中序遍历,后序遍历

(可以用栈去模拟递归,递归的实现本身就是用栈这种数据结构去实现的)

2.广度优先搜索:

包括层序遍历

3.总结

二叉树是一种基础的数据结构,我们应当去了解其分类,以及存储方式还有他的遍历顺序

同时我们也应当了解他的定义方式,要能够自己去定义一个二叉树,在二叉树章节中,我们会发现递归出现的频率非常高,所以在这里我也再次复习一下我们的递归三部曲

1.明白这个递归函数到底要干嘛,以及它的参数是什么

2.明白这个递归的结束条件

3.单层递归都需要去遍历哪些元素

4.相关例题

第一题:美国血统

题解:通过前序第一个可以确定根节点,然后在中序就可以判断出来左子树和右子树,然后一直递归,先调用左子树,将左子树的结点输出,在调用右子树,将右子树的结点输出,最后输出最后的根结点

AC代码:

#include<bits/stdc++.h>
using namespace std;
void dfs(string a,string b)
{if((int)b.size()==0)//如果前序遍历里的数组为空的话,说明遍历完了,该返回上一层了{return ;}int flag=a.find(b[0]);//找到根结点的坐标dfs(a.substr(0,flag),b.substr(1,flag));//遍历左子树dfs(a.substr(flag+1),b.substr(flag+1));//遍历右子树printf("%c",b[0]);//输出最后的根结点
}
int main()
{char x[30];//中序遍历char y[30];//前序遍历scanf("%s",x);scanf("%s",y);dfs(x,y);return 0;
}

第二题:新二叉树

题解:由于是顺序输出,且第一个就是根结点,我们只需要用深搜去一搜到底就可以,找出所有的情况,但是这个地方不需要回溯,只需要找出先后出现的就可以,所以在内部要先搜索左子树,再搜索右子树

AC代码:

#include<bits/stdc++.h>
using namespace std;char c[27][4];
void dfs(char t,int n)
{if(t=='*'){return ;}for(int i=0;i<n;i++){if(c[i][0]==t){printf("%c",t);dfs(c[i][1],n);//搜索左子树dfs(c[i][2],n);//搜索右子树}}
}
int main()
{int n;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%s",c[i]);}dfs(c[0][0],n);return 0;
}

5.寄语:(写给每一个正在低谷期努力的人)

你也走了很远的路吧

每个人在最悲伤的时候会突然消失一阵子

到底发生了什么,我来告诉你

世间降临了一场暴雨

天上所有的星星都自杀身亡

但你要相信从此以后晴空万里

耐心点 你会做到的

那些曾经最孤单 最无望 最失落,最安静的经历

其实都不是你最潦倒的时光

你憋着这口气,最终能独自上岸

你耐住了孤单 扛过了无望,不再怕失落,也学会与安静为伴

虽然疼都是别人给的,但伤都是自己好的

你要忍,忍到春暖花开

你要走,走到灯火通明

你要看过世界辽阔 再评判是好是坏

你要铆足劲变好,再站在不敢想象的人身边 ,旗鼓相当

你要变成想象中的样子,这件事,一步都不能让

愿我们都有足够的运气与勇气,去遇见命里不同的风

愿你的世界,星光满载,初心不改,走过汹涌的人潮,历经生活的磨难,终遇良人

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

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

相关文章

R语言学习case7:ggplot基础画图(核密度图)

step1: 导入ggplot2库文件 library(ggplot2)step2&#xff1a;带入自带的iris数据集 iris <- datasets::irisstep3&#xff1a;查看数据信息 dim(iris)维度为 [150,5] head(iris)查看数据前6行的信息 step4&#xff1a;画图展示 plot2 <- ggplot(iris,aes(Sepal.W…

海外云手机运营Instagram攻略

Instagram是世界著名的社交媒体平台&#xff0c;有着10亿实时用户&#xff0c;是跨境电子商务的优质流量来源。平台以女性用户为主&#xff0c;购物倾向高&#xff0c;转化率好。它被公认为外贸行业的优质社交媒体流量池。那么&#xff0c;如何使用海外云手机吸引Instagram上的…

表贴式PMSM的直接转矩控制(DTC)MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 表贴式PMSM的直接转矩控制(DTC),直接使用滞环控制对转矩和磁链进行控制&#xff0c;相对于传统的FOC控制而言&#xff0c;其不需要进行解耦变换&#xff0c;在此次的有以下几点需要注意&#xff1a…

血细胞分类项目

血细胞分类项目 数据集&#xff1a;血细胞分类数据集数据处理 dataset.py网络 net.py训练 train.py拿训练集的几张图进行预测 数据集&#xff1a;血细胞分类数据集 https://aistudio.baidu.com/datasetdetail/10278 数据处理 dataset.py from torchvision import transfor…

2024-01-29 ubuntu 用脚本设置安装交叉编译工具链路径方法,设置PATH环境变量

一、设置PATH环境变量的方法,建议用~/.bash_profile的方法&#xff0c;不然在ssh登录的时候可能没有设置PATH. 二、下面的完整的脚本&#xff0c;里面的echo "export PATH$build_toolchain_path:\$PATH" >> $HOME/.bashrc 就是把交叉编译路径写写到.bashrc设置…

Netty源码二:服务端创建NioEventLoopGroup

示例 还是拿之前启动源码的示例&#xff0c;来分析NioEventLoopGroup源码 NioEventLoopGroup构造函数 这里能看到会调到父类的MultiThread EventLoopGroup的构造方法 MultiThreadEventLoopGroup 这里我们能看到&#xff0c;如果传入的线程数目为0&#xff0c;那么就会设置2倍…

/etc/profile错误,命令失效

source /etc/profile后所有命令失效 执行 export PATH/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin 修改后 执行:wq! 执行:w !sudo tee %

TCP_拥塞控制

引言 24年春节马上就要到了&#xff0c;作为开车党&#xff0c;最大的期盼就是顺利回家过年不要堵车。梦想是美好的&#xff0c;但现实是骨感的&#xff0c;拥堵的道路让人苦不堪言。 在网络世界中&#xff0c;类似于堵车的问题也存在&#xff0c;而TCP&#xff08;Transmissi…

(一)Spring 核心之控制反转(IoC)—— 配置及使用

目录 一. 前言 二. IoC 基础 2.1. IoC 是什么 2.2. IoC 能做什么 2.3. IoC 和 DI 是什么关系 三. IoC 配置的三种方式 3.1. XML 配置 3.2. Java 配置 3.3. 注解配置 四. 依赖注入的三种方式 4.1. 属性注入&#xff08;setter 注入&#xff09; 4.2. 构造方法注入&a…

【更新】人工智能-55个工具变量汇总(2024年更新)

一、引言 工具变量是一种在统计学和计量经济学中常用的技术&#xff0c;用于处理因果关系研究中的内生性问题。内生性问题通常是由于遗漏变量、双向因果关系或测量误差等原因造成的&#xff0c;这会导致估计结果出现偏误。工具变量的使用可以帮助解决这一问题 整理收集了CSSC…

Android MediaCodec 简明教程(四):使用 MediaCodec 将视频解码到 Surface,并使用 SurfaceView 播放视频

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…

【大数据】Flink SQL 语法篇(二):WITH、SELECT WHERE、SELECT DISTINCT

Flink SQL 语法篇&#xff08;二&#xff09; 1.WITH 子句2.SELECT & WHERE 子句3.SELECT DISTINCT 子句 1.WITH 子句 应用场景&#xff08;支持 Batch / Streaming&#xff09;&#xff1a;With 语句和离线 Hive SQL With 语句一样的&#xff0c;语法糖 1&#xff0c;使用…

inode生命周期

1.添加inode到inode cache链表 当inode的引用计数器i_count为0后&#xff0c;会调用iput_final去释放 static void iput_final(struct inode *inode) {struct super_block *sb inode->i_sb;const struct super_operations *op inode->i_sb->s_op;unsigned long sta…

PaddleNLP的简单使用

1 介绍 PaddleNLP是一个基于PaddlePaddle深度学习平台的自然语言处理&#xff08;NLP&#xff09;工具库。 它提供了一系列用于文本处理、文本分类、情感分析、文本生成等任务的预训练模型、模型组件和工具函数。 PaddleNLP有统一的应用范式&#xff1a;通过 paddlenlp.Task…

数据结构-数组(详细讲解)

文章目录 数组数组的概述数组的图示一维数组二维数组 数组的定义一维数组的定义二维数组的定义 数组的取值赋值一维数组二维数组 数组的操作一维数组的操作索引实现指针实现 二位数组的操作矩阵转三元组矩阵的乘法 数组 数组的概述 概述&#xff1a;数组是一种线性数据结构&a…

C# 使用WMI监听进程的启动和关闭

写在前面 Windows Management Instrumentation&#xff08;WMI&#xff09;是用于管理基于 Windows 操作系统的数据和操作的基础结构。具体的API可以查看 WMI编程手册。 WMIC 是WMI的命令行管理工具&#xff0c;使用 WMIC&#xff0c;不但可以管理本地计算机&#xff0c;还可…

粒子群算法求解港口泊位调度问题(MATLAB代码)

粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;PSO&#xff09;是一种基于群体智能的优化算法&#xff0c;它通过模拟鸟群或鱼群的行为来寻找最优解。在泊位调度问题中&#xff0c;目标是最小化所有船只在港时间的总和&#xff0c;而PSO算法可以帮助我们找到一…

Java把列表数据导出为PDF文件,同时加上PDF水印

一、实现效果 二、遇到的问题 实现导出PDF主体代码参考&#xff1a;Java纯代码实现导出PDF功能&#xff0c;下图是原作者实现的效果 导出报错Font STSong-Light with UniGB-UCS2-H is not recognized.。参考&#xff1a;itext 生成 PDF(五) 使用外部字体 网上都是说jar包的版本…

FastBee开源物联网平台2.0开源版发布啦!!!

一、项目介绍 物美智能(wumei-smart)更名为蜂信物联(FastBee)。 FastBee开源物联网平台&#xff0c;简单易用&#xff0c;更适合中小企业和个人学习使用。适用于智能家居、智慧办公、智慧社区、农业监测、水利监测、工业控制等。 系统后端采用Spring boot&#xff1b;前端采用…

成功解决AttributeError: ‘str‘ object has no attribute ‘decode‘

成功解决AttributeError: ‘str’ object has no attribute ‘decode’. &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;报错分析及解决方案&#x1f333;&#x1f333;参考文章&#x1f333;&#x1f333;结尾&#x1f333; &#x1f333;引…