【(C语言)数据结构奋斗100天】二叉树(上)
创始人
2024-05-23 23:09:18
0

【(C语言)数据结构奋斗100天】二叉树(上)

🏠个人主页:泡泡牛奶

🌵系列专栏:数据结构奋斗100天

本期所介绍的是二叉树,那么什么是二叉树呢?在知道答案之前,请大家思考一下下列问题:

  1. 什么是二叉树的根节点?
  2. 什么是二叉树的左子树和右子树?
  3. 什么是二叉树的父节点和子节点?
  4. 二叉树的遍历有哪些方法?

让我们带着这些问题,开始今天的学习吧( •̀ ω •́ )✧

一、树和二叉树

1. 什么是树?

树是一种非线性的数据结构,是(n>=0)个节点的有限集合。当n=0时,称为空树。在任意一颗非空树中,我们可以看到节点的排列就像一颗倒着的树,根朝上,叶子朝下

367-3671401_bianry-tree-hd-png-download

在现实生活中有哪些像上面根朝上,叶子朝下的树型结构呢🤔?

wp7002672

例如一个家族里组成的 “家谱” ,就是一颗树。

再例如一个阶级关系就是一颗 “树”。

1634653354_378339_url

除开人与人的关系,还有很多抽象的东西也可以成为一颗 “树”,如一本书的目录,如操作系统的文件系统。

d0c50-linux2bfile2bsystem2bhierarchy

以上的共同点都是由一个 “根” 衍生出许多的 “枝干”,再从每一个 “枝干” 衍生出更多的 “叶子”。

在数据结构中,我们对树有以下称呼:

image-20230207195022422
  • 父节点/双亲节点:某节点的上一个节点为父节点,例如:C是F的父节点
  • (孩)子节点:某一节点指向的下一个节点为子节点,例如:F是C的子节点
  • 兄弟节点:父节点相同的节点互为兄弟节点,例如:D、E
  • 堂兄弟节点:双亲在同一层的节点互为堂兄弟,例如:D、F互为堂兄弟节点
  • 节点的:一个节点含有的子树的个数称为该节点的度,例如:B的度为2,C的度为1
  • 叶子节点度为0,或者无子节点的称为叶子节点,例如:G、E、F
  • 树的度:一颗树中的最大的节点的度,例如:上图树的度为2
  • 节点的层次根节点第一层, 依次类推
  • 树的高度/深度:树节点的最大层次,如上图树的高度为4
  • 节点的祖先:根节点到此节点的经过的所有节点都为祖先,例如:A是所有节点的祖孙
  • 子孙:只要在关系在某一节点的下面都为子孙
  • 森林:有(m > 0)的树所组成的集合称为森林

小结:

树的关系可以由现实生活中的亲戚关系来表示

2. 什么是二叉树?

什么是 n叉树

n叉树,故名思意,就是树的分叉最多可以有n个

8QA22

那么二叉树就是,最多有2个孩子节点的树。如下图所示。

image-20230207201745581

二叉树节点的两个孩子,一个被称为左孩子,一个被称为右孩子。这两个孩子的顺序是固定的。

3. 二叉树的类型

单二叉树的类型来说,其实有很多种,普通二叉树、满二叉树、完全二叉树、搜索二叉树、AVL树、红黑树……而今天我们的主题就是满二叉树和完全二叉树

一颗二叉树的所有非叶子节点都存在左右孩子,并且所有叶子节点都在同一层级上,那么这就是满二叉树,如下图。

满二叉树的总节点数为Sn=2n−1S_n = 2^{n}-1Sn​=2n−1 (n为层数)

image-20230207212512657

对一个有n个节点的二叉树,按层级需要编号,则所有节点编号从1到n。如果这颗树的所有节点和同样深度的满二叉树的编号为1到n的节点位置相同,则这个二叉树为完全二叉树。如下图。(简单来说,最后一层连续排布,但不满就是完全二叉树)

image-20230207215651564

4. 二叉树的规律性质

image-20230207205933509
  • 这是一个公比为2的等比数列,首项为1。即 a1=1a_1=1a1​=1,公比 q=2q=2q=2。
  • 第n层节点的数量为 2n−12^{n-1}2n−1,前n层节点的数量总和为 Sn=2n−1S_n=2^n-1Sn​=2n−1。
  • 对于任意一棵二叉树,满足 n=n0+n1+n2n=n_0+n_1+n_2n=n0​+n1​+n2​,其中 nnn 为节点总数,n0n_0n0​ 表示度数为0的节点个数,n1n_1n1​ 表示度数为1的节点个数,n2n_2n2​ 表示度数为2的节点个数。
  • 存在 n2=n0−1n_2=n_0-1n2​=n0​−1 的关系。
  • 计算层数 nnn 的公式为 n=log⁡2(N+1)n=\log_2(N+1)n=log2​(N+1),其中 NNN 为节点总数。

上面这些规律往往会在刷题中使用到

二、二叉树的存储结构

链式结构和顺序结构是二叉树的两种常见存储方式。

1. 顺序结构

顺序存储结构使用数组作为基础存储单元,它适用于表示完全二叉树。除了堆,其他情况使用数组存储会则会造成大量空间浪费。顺序存储结构的二叉树在物理结构上是一个数组,逻辑结构上是一棵二叉树。

2019-05-16-10

用数组来存储,我们通常会通过下标来访问元素,观察节点规律,我们不难发现:

  • 若父节点为 father,子节点为 child,则满足:

    father=child−12father = \frac{child - 1}{2}father=2child−1​

  • 若左右子节点分别为 leftright,并且左右孩子都存在(即 left,right≥nleft, right \ge nleft,right≥n),则满足:

    left=father∗2+1left = father * 2 + 1left=father∗2+1

    right=father∗2+2right = father * 2 + 2right=father∗2+2

2. 链式结构

链式结构使用指针作为底层容器,通过指向子节点的指针来表示树的逻辑结构。这种方式在存储灵活性和空间利用效率方面优于顺序结构。通用方法是链表中每个节点由三个域组成:数据域和左右指针域。

typedef int treeType;//将int重定义为type_t
typedef struct TreeNode
{treeType val;			//表示数据TreeNode* left;	//表示左孩子TreeNode* right;	//表示右孩子
}TreeNode;

(图片)

总的来说,选择使用链式结构还是顺序结构要根据具体的存储需求来决定。

三、二叉树的遍历

当我们介绍数组、链表时,为什么没有着重研究他们的遍历过程呢?

二叉树的遍历又有什么特殊之处?

在计算机程序中,遍历线性结构的数组或链表是一件简单的事情。相反,二叉树是一种典型的非线性数据结构,遍历时需要将非线性关系的节点转化为线性序列。

二叉树的遍历可以根据节点的直接位置关系分为两类:

  1. 深度优先遍历(前序遍历、中序遍历、后续遍历)
  2. 广度优先遍历(层序遍历)

下面就来看看这些不同的遍历方式吧ο(=•ω<=)ρ⌒☆

1. 深度优先遍历

  1. 前序遍历

二叉树的前序遍历,遍历顺序为根节点、左子树、右子树,当遇到空指针NULL时返回。

二叉树1

代码示例如下:

void PreOrder(TreeNode* root)
{if (root == NULL){return;}//先取出当前节点元素,再对其进行相关操作printf("%d", root->val);InOrder(root->left);//遍历左节点InOrder(root->right);//遍历右节点
}
  1. 中序遍历

二叉树的中序遍历,遍历顺序为左子树、根节点、右子树,当遇到空指针NULL时返回。

二叉树2

代码示例如下:

void InOrder(TreeNode* root)
{if (root == NULL){return;}InOrder(root->left);//遍历左子树printf("%d", root->val);//取出元素,进行操作InOrder(root->right);//遍历右子树
}
  1. 后序遍历

二叉树的后序遍历,遍历顺序为左子树、右子树、根节点,当遇到空指针NULL时返回。

二叉树3

代码示例如下:

void PostOrder(TreeNode* root)
{if (root == NULL){return;}PostOrder(root->left);//遍历左子树PostOrder(root->right);//遍历右子树printf("%d", root->val);//取出元素,进行操作
}

2. 广度优先遍历

广度优先遍历,按层次遍历,从根节点开始,按从上至下,从左至右的顺序遍历二叉树的所有节点。

使用广度优先算法,我们通常需要借用队列这个数据结构来实现(不知道队列的,或者没看过这篇文章的,赶紧取看看🚀传送门

接下来我们就会使用队列来完成我们所需要的操作。

二叉树4

这是上一期的队列节点结构,我们需要把QueueType的类型改为TreeNode*来存放我们的节点:

typedef TreeNode* QueueType;//改为TreeNode*typedef struct QueueNode
{QueueType value;struct QueueNode* next;
}QueueNode;

而这也就是为什么我们需要对类型typedef的原因,可以方便我们做修改φ(゜▽゜*)♪

遍历代码示例如下:

void LevelOrder(TreeNode* root)
{Queue q;queue_init(&q);queue_push(&q, root);while (!queue_empty(&q)){TreeNode* cur = queue_front(&q);queue_pop(&q);if (cur == NULL){continue;}printf("%d", cur->val);//取出元素,进行操作queue_push(&q, cur->left);queue_push(&q, cur->right);}//不要忘了释放Queuequeue_destory(&q);
}

在刷题过程中,单纯只是这样,多半会有些不够,接下来我们就把代码进一步优化吧:

void LevelOrder(TreeNode* root)
{Queue q;queue_init(&q);int level = 0; //表示当前层数<------------queue_push(&q, root);while (!queue_empty(&q)){TreeNode* cur = queue_front(&q);queue_pop(&q);//--------------------------------------------------int level_size = queue_size(&q);//获取当前层的元素个数for (int i = 0; iprintf("%d", cur->val);//取出元素,进行操作//对当前节点的左右子节点进行判断,若为空便没有必要入队列if (cur->left != NULL){queue_push(&q, cur->left);}if (cur->right != NULL){queue_push(&q, cur->right);}}
//---------------------------------------------------++level;//层数+1 <------------}//不要忘了释放Queuequeue_destory(&q);
}

当每一层入完队列之后,队列内的元素个数一定是下一层的元素个数(可以简单的画一个图来看看,这里就给大家布置一个小问题,让你们自己来理解吧(*^-^*)

四、小结

二叉树是树形结构的一种,其中每个节点最多有两个子节点。二叉树有多种遍历方法,包括深度优先遍历和广度优先遍历。

深度优先遍历有三种:

  • 前序遍历
  • 中序遍历
  • 后序遍历

分别对应的遍历顺序为:

  • 根节点、左子树、右子树

  • 左子树、根节点、右子树

  • 左子树、右子树、根节点

广度优先遍历的遍历顺序是从上到下、从左到右

点赞是对博主的鼓励和支持!🤗 希望你们看完这篇博客后,不妨给博主一个大大的三连👍,表示对内容的赞赏!😊 当然,如果你是真心被内容打动,那么点个四连甚至五连都是博主最大的动力!💪 让我们一起用简单幽默的语气,为点赞助力!ο(=•ω<=)ρ⌒☆
题,让你们自己来理解吧(*^-^*)

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...