数据结构初阶之二叉树的详细解析

这篇具有很好参考价值的文章主要介绍了数据结构初阶之二叉树的详细解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页:点我进入主页

专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶

C语言刷题       数据结构初阶    Linux

欢迎大家点赞,评论,收藏。

一起努力,共赴大厂。

目录

1.前言 

2.二叉树各个功能代码实现

2.1二叉树结构体

2.2二叉树的前序遍历 

2.3中序遍历 

2.4后序遍历

2.5计算二叉树节点个数

2.6计算二叉树叶子节点的个数 

2.7计算二叉树的深度

2.8计算第k层的节点个数

2.9层序遍历

2.10层序遍历变式

2.11判断是否为完全二叉树

2.12二叉树内存释放

2.13树的创建

3.二叉树的性质

4.总结


1.前言 

        我在前面写过关于顺序表,栈,队列,堆的存储结构,现在我们还有一种一对多的存储结构树,在堆的博客中我写过一些树的概念,树的增删查改在我们的应用中并不实用,其中有用的是查找树,但是查找树的实现我们还没有能力去实现,树的实现可以用顺序表实现也可以用链表去实现,这次我们用链式二叉树去实现,利用顺序表实现可以看堆的内容。在这篇文章中我主要给大家带来关于二叉树的创建,树的一些性质,树的前序中序后序层序遍历,求树的节点个数,叶子节点个数,树的深度,第k层节点的个数,判断是不是完全二叉树,在这些中大部分需要用递归,我会给搭建展示部分功能的递归展开图来帮助大家理解,在学习这写内容中我建议大家可以会回忆一下递归的内容,是不是看到递归就觉得畏惧吗?其实我们只需要多去感受一下其中的思路与思想,不用过多的去畏惧递归,接下来就让我们看看其中是如何用递归去实现吧。

2.二叉树各个功能代码实现

2.1二叉树结构体

typedef struct BiTreeNode {
	int val;
	struct BiTreeNode* left, * right;
}BTNode;

结构体的内容包括结构体的内容,指向二叉树的左孩子的指针,指向二叉树的右孩子的指针。我给大家来看一下二叉树的大概的模型

数据结构初阶之二叉树的详细解析,数据结构初阶,数据结构

2.2二叉树的前序遍历 

void PrevorderBTNode(BTNode* root)
{
	if (root == NULL)
		return;
	printf("%d ", root->val);
	PrevorderBTNode(root->left);
	PrevorderBTNode(root->right);
}

例如我们利用上面的二叉树进行模拟

数据结构初阶之二叉树的详细解析,数据结构初阶,数据结构

我们可以根据代码展开图进行一步步实现代码实现的过程,最好我们自己去画一画代码展开图这样对于我们去了解递归会有非常好的作用。

2.3中序遍历 

void InorderBTNode(BTNode* root)
{
	if (root == NULL)
		return;
	InorderBTNode(root->left);
	printf("%d ", root->val);
	InorderBTNode(root->right);
}

我们的代码展开图如下数据结构初阶之二叉树的详细解析,数据结构初阶,数据结构

 我们可以看到我们的中序遍历代码和前序遍历代码大致相同,相差的只是代码的顺序,我们可以将大部分二叉树的递归可以表示为根节点,左孩子右孩子,左子树右子树和根节点,左孩子右孩子这两种,这非常有用是一种分治的思想。

2.4后序遍历

void PostorderBTNode(BTNode* root)
{
	if (root == NULL)
		return;
	PostorderBTNode(root->left);
	PostorderBTNode(root->right);
	printf("%d ", root->val);
}

在这里我们不给代码展开图了,大家可以自己去画一画代码展开图。

2.5计算二叉树节点个数

int BTreeSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	return BTreeSize(root->left) + BTreeSize(root->right) + 1;
}

我们想到二叉树的递归内容可以表示为根节点,左孩子右孩子,左子树右子树或根节点,左孩子右孩子,我们可以看成根节点,左子树右子树,当根节点为空时我们返回0,我们分为左子树和右子树所以我们返回BTreeSize(root->left) + BTreeSize(root->right) + 1进行递归,我们的递归展开图可以画为

数据结构初阶之二叉树的详细解析,数据结构初阶,数据结构

2.6计算二叉树叶子节点的个数 

        我们可以根据根据根节点,左子树右子树进行分治,当我们的根节点为空时返回0,当左孩子和右孩子为空是叶子节点返回1,对于左子树和右子树我们进行递归。

int BTreeLeafSize(BTNode* root)
{
	if (root == NULL)
		return 0;
	if (root->left == NULL && root->right == NULL)
		return 1;
	return BTreeLeafSize(root->left) + BTreeLeafSize(root->right);
}

递归展开图和上面的相似,大家可以自己去画一画。

2.7计算二叉树的深度

 我们可以根据根据根节点,左子树右子树进行分治,当根节点为空时返回0,然后进行递归。

int BTreeDeap(BTNode* root)
{
	if (root == NULL)
		return 0;
	return (int)fmax(BTreeDeap(root->left), BTreeDeap(root->right)) + 1;
}

2.8计算第k层的节点个数

int BTreeLeafkSize(BTNode* root,int k)
{
	if (root == NULL)
		return 0;
	if (k == 1)
		return 1;
	return BTreeLeafkSize(root->left, k-1) + BTreeLeafkSize(root->right, k-1);
}

当我们的根节点是空时我们返回0,当我们的k变成1时我们返回1,根据左子树右子树进行分治每次都让k-1。

2.9层序遍历

void Levelorder(BTNode* root)
{
	Queue queue;
	QueueInit(&queue);
	if (root)
	{
		QueuePush(&queue, root);
	}
	while (!QueueEmpty(&queue))
	{
		BTNode* prev = top(&queue) ;
		QueuePop(&queue);
		if (prev->left)
			QueuePush(&queue, prev->left);
		if (prev->right)
			QueuePush(&queue, prev->right);
		printf("%d ", prev->val);
	}
}

在层序遍历中我们利用队列进行存储,先将非空的根节点进行插入,进行循环队列不为空进行循环,利用一个二叉树的指针指向队头的元素(队列里的元素存的是二叉树的节点时结构体的指针所以我们可以用二叉树的指针进行指向),然后出队,入指针的非空左孩子右孩子,每次打印指针对应的值。

2.10层序遍历变式

        如果我们想每层打印时打印完每次会输出一个换行,这时候我们应该如何作呢?我们首先想到的是再搞一个队列,存放第一个队列元素是第几层,但是我们c语言去实现队列是非常麻烦的,连结构体都需要我们去重新设定,那我们应该如何去做呢?在我们的层序遍历中你有没有注意到我们的队列中总是存在全部的一层元素或者一层与下一层的元素这两种情况,什么时候会出现只有一层的元素呢?那就是上一层全部出队了,这便是我们的突破点,当我们将非空根节点入队后我们引入一个变量存放队中的元素的个数然后进入循环,此时这个变量就是一层元素的个数,我们每次出一个元素就让这个变量减1,这也就是我们的循环条件,循环结束后我们重新计算这个变量的值,这时候队中还是只有一层全部的节点,此时变量的值就是队中元素的个数。

2.11判断是否为完全二叉树

bool BinaryTreeComplete(BTNode* root)
{
	Queue queue;
	QueueInit(&queue);
	if (root)
		QueuePush(&queue, root);
	while (top(&queue))
	{
		BiTreeNode* front = top(&queue);
		QueuePop(&queue);
		QueuePush(&queue, front->left);
		QueuePush(&queue, front->right);
	}
	return QueueEmpty(&queue);

}

首先我们需要了解完全二叉树的性质,他和满二叉树类似,但是序号必须和满二叉树相同,这时候我们采用层序遍历的方式进行判断,我们将非空根节点入队,判断条件是队头元素不是空,每个节点入队当我们遇到空节点时我们判断队是不是都是空节点,如果是就是完全二叉树,为什么这样可以呢?当我们入队后一旦想出某一层时这一层的全部节点就会入队,然后进行判断就可以了。

2.12二叉树内存释放

二叉树内存前序中序后序都可以实现,但是我们如何做才能让这个操作根号的实现呢?我们想类似于前中后序遍历的样子进行,这时候你会发现,利用前序和中序遍历会提前将节点释放,以至于我们不能找到其他的节点,但是我们采用后序遍历就完美的避免了这个问题,所以我们在释放二叉树时我们经常采用后序遍历的方式。

void BTNodeDestory(BTNode* root)
{
	if (root == NULL)
		return;
	BTNodeDestory(root->left);
	BTNodeDestory(root->right);
	free(root);
}

2.13树的创建

BiTree* BiTreeCreate(BiTree* bt)
{
	bt = (BiTree*)malloc(sizeof(BiTree));
	char ch;
	scanf("%c", &ch);
	if (ch != '#')
	{
		bt->data = ch;
		bt->lchild = BiTreeCreate(bt);
		bt->rchild = BiTreeCreate(bt);
	}
	else
		bt = NULL;
	return bt;
}

3.二叉树的性质

1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有 个结点.
2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是 .
3. 对任何一棵二叉树, 如果度为0其叶结点个数为 , 度为2的分支结点个数为 ,则有 = +1
4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= . (ps: 是log以2
为底,n+1为对数)
5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对
于序号为i的结点有:
1. 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
2. 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
3. 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子

4.总结

        事实上我们二叉树的内容并不是很难,更多的需要我们去理解,这就需要我们多去感受一线二叉树的实现,最后希望大家可以来三连。到这里我们树的内容就解决了三分之二,其余的三分之一我会将以C++的形式来为大家讲解,不过可能会等上一段时间了。在下一篇文章中我会给大家带来一些二叉树的题目,欢迎大家持续关注。文章来源地址https://www.toymoban.com/news/detail-753823.html

到了这里,关于数据结构初阶之二叉树的详细解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构之二叉树和平衡二叉树

    1、二叉树: 2、平衡二叉树:

    2024年04月17日
    浏览(33)
  • 11. 数据结构之二叉树

    上一节,简单概述了树这种数据结构,以及树结构向下,具有某些一些特征的树,比如二叉树,B树,B+树,堆等。其中,二叉树是一个很重要的模块。也是在一些技术面试中,可能会问到的问题。本节,我们就二叉树,做详细介绍。 二叉树是一个 逻辑结构 , 底层可以用数组

    2024年02月07日
    浏览(28)
  • 数据结构之二叉树简介

    二叉树是一种非线性数据结构,代表“祖先”与“后代”之间的派生关系,体现了“一分为二”的分治逻辑。与链表相似,二叉树的基本单元是节点,每个节点包含值,左子节点的索引,右子节点的索引 当给定一个二叉树的节点时,我们将该节点的左子节点及其以下节点形成

    2024年02月01日
    浏览(31)
  • 数据结构之二叉树(详细版)

            二叉树作为数据结构的一种,尤为重要,下面是对二叉树的详细讲解。想要了解二叉树,首先要了解 二叉树的基本概念,以及创建二叉树的结构,再深层点,遍历二叉树的前序中序和后续,其次是层序,后面将会讲解如何计算二叉树的高和叶结点 等等。        

    2024年02月03日
    浏览(32)
  • 数据结构之二叉树(Java)

    在这里先说明一下,结点和节点其实一样的,无须关注这个。 1. 概念:树是一种非线性的数据结构,它是由n个有限节点组成一个具有层次关系的集合。 如上图所示,把此种数据结构称作树是因为它看起来像一个倒挂的树。  2. 特点 有一个特殊的节点,称为根节点,它是唯一

    2024年02月07日
    浏览(24)
  • 数据结构之二叉树的实现

    目录 前言 1. 二叉树的遍历 1.1二叉树的前、中、后序遍历 1.2 层序遍历 2.二叉树的实现 2.1 二叉树的结构 2.2构建二叉树  2.2 前序遍历的实现 2.3 中序遍历的实现 2.4 后序遍历的实现 2.5 计算树的节点个数 2.6 计算树的深度 2.7 计算叶子节点个数 2.8 计算树第k层的节点数 2.9 以内容

    2023年04月10日
    浏览(32)
  • 《数据结构与算法》之二叉树(补充树)

    二叉搜索树,也称二叉排序树或二叉查找树 二叉搜索树:一棵二叉树,可以为空,如果不为空,应该满足以下性质: 非空左子树的所有结点小于其根结点的键值 非空右子树的所有结点大于其根结点的键值 左右子树都是二叉搜索树 对于二叉树的查找,其实沿用的是分治法的

    2024年02月08日
    浏览(32)
  • 数据结构之二叉树的性质与存储结构

      数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法,为提高利用

    2024年01月21日
    浏览(38)
  • 数据结构之二叉树的数组表示

    若某节点的索引为 i ,则该节点的左子节点的索引为 2i+1 ,右子节点的索引为 2i+2 给定某节点,获取它的左右字节点,父节点 获取前序遍历,中序遍历,后序遍历,层序遍历

    2024年01月18日
    浏览(39)
  • 【数据结构之二叉树的构建和遍历】

    前言: 前篇学习了 数据结构之树和二叉树的基本概念知识,那么这篇继续完善二叉树的相关知识并完成实现二叉树的构建和遍历的内容。 / 知识点汇总 / 因为前篇已经非常详细的单独学习了数和二叉树的基本知识概念,那么这里就简单回顾一下即可。 概念 : 二叉树(Bina

    2024年02月21日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包