数据结构与算法之《二叉树》详解

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

标题:二叉树的思路及代码实现

作者:@Ggggggtm

寄语:与其忙着诉苦,不如低头赶路,奋路前行,终将遇到一番好风景

文章目录

一、树的概念及结构

二、二叉树的概念及结构

2、1 二叉树的概念

2、2 二叉树的特点

2、3 二叉树的结构(图片)

2、4 特殊的二叉树

三、二叉树的代码及思路实现

3、1 二叉树的存储结构

3、1、1 二叉树的顺序存储结构

3、1、2 二叉树的链式存储结构

3、2 二叉树链式结构的实现

3、2、1 定义结构体

3、2、2 自定义一个二叉树

3、2、3 前序遍历

3、2、4 中序遍历

3、2、5 后序遍历

3、2、6 求树中节点的个数

3、2、7 求树中叶节点的个数

3、3 二叉树的性质


数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

一、树的概念及结构

  二叉树是树的一种,所以在学习二叉树之前我们先了解一下树的概念及结构。

  树是一种 非线性 的数据结构,它是由 n n>=0 )个有限节点组成一个具有层次关系的集合。 把它 叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的
  • 有一个特殊的结点,称为根结点,根节点没有前驱结点;
  • 除根节点外,其余结点被分成M(M>0)个互不相交的集合T1T2……Tm,其中每一个集Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以 0个或多个后继;
  • 因此,树是递归定义的。  

数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

这里还有我们熟知的树中的一些概念:

  • 节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为6;
  • 叶节点或终端节点:度为 0 的节点称为叶节点; 如上图: B C H I... 等节点为叶节点;
  • 非终端节点或分支节点:度不为 0 的节点; 如上图: D E F G... 等节点为分支节点;
  • 双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图: A B 的父节点;
  • 孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图: B A 的孩子节点
  • 兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图: B C 是兄弟节点;
  • 树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为 6;
  • 节点的层次:从根开始定义起,根为第 1 层,根的子节点为第 2 层,以此类推;
  • 树的高度或深度:树中节点的最大层次; 如上图:树的高度为 4;
  • 节点的祖先:从根到该节点所经分支上的所有节点;如上图: A 是所有节点的祖先;
  • 子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是 A 的子孙;
  • 森林:由 m m>0 )棵互不相交的多颗树的集合称为森林;(数据结构中的学习并查集本质就是 一个森林);

  在这里我们要注意树与非树的区别是;

  • 子树是不相交的;
  • 除了根结点外,每个节点有且仅有一个父结点;
  • 一颗N个结点的树有N-1条边。

以下我给大家举几个树和非树的例子,可以先简单了解以下。

树:

数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

非树:

数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

二、二叉树的概念及结构

2、1 二叉树的概念

  一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子树和右子树的二叉树组成。

2、2 二叉树的特点

  • 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
  • 二叉树的子树有左右之分,其子树的次序不能颠倒。

2、3 二叉树的结构(图片)

数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

2、4 特殊的二叉树

  1. 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉 树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。
  2. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对 于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号 从1n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

三、二叉树的代码及思路实现

3、1 二叉树的存储结构

   二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构

3、1、1 二叉树的顺序存储结构

  顺序结构存储就是使用 数组来存储 ,一般使用数组 只适合表示完全二叉树 ,因为不是完全二叉树 会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。

3、1、2 二叉树的链式存储结构

  二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成数据域左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链,当前我们学习中一般都是二叉链。

3、2 二叉树链式结构的实现

  二叉树的链式结构实现都有哪些模块呢?接下来我简单的给大家总结一下:

  1. 定义结构体;
  2. 自定义一个二叉树;
  3. 前序遍历;
  4. 中序遍历;
  5. 后序遍历;
  6. 求树中节点的个数;
  7. 求叶节点的个数。

接下来我们来看一下各个模块实现的细节以及详解。

3、2、1 定义结构体

   定义结构体时,由上面的链式存储结构我们直到该结构体应该包含一个存储数据的变量,和指向左右分支节点的指针;我们看代码实现。

typedef char BTDataType;
typedef struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	BTDataType data;
}BTNode;

3、2、2 自定义一个二叉树

  首先我们自己要有一个二叉树,简单的二叉树即可。因为下面的操作都是在二叉树上进行的。这里给出一个简单的二叉树,如下图及代码实现:

数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

	BTNode* A = (BTNode*)malloc(sizeof(BTNode));
	A->data = 'A';
	A->left = NULL;
	A->right = NULL;

	BTNode* B = (BTNode*)malloc(sizeof(BTNode));
	B->data = 'B';
	B->left = NULL;
	B->right = NULL;

	BTNode* C = (BTNode*)malloc(sizeof(BTNode));
	C->data = 'C';
	C->left = NULL;
	C->right = NULL;

	BTNode* D = (BTNode*)malloc(sizeof(BTNode));
	D->data = 'D';
	D->left = NULL;
	D->right = NULL;

	BTNode* E = (BTNode*)malloc(sizeof(BTNode));
	E->data = 'E';
	E->left = NULL;
	E->right = NULL;
	
	A->left = B;
	A->right = C;
	B->left = D;
	B->right = E;

3、2、3 前序遍历

  什么是前序遍历呢?我们先来看一下比较官方的解释。

  NLR :前序遍历(Preorder Traversal 亦称先序遍历 )—— 访问根结点的操作发生在遍历其左右子树之前。

   我在稍微解释一下前序遍历的概念:其实就是遍历树时,先访问根,再访问左子树,最后访问右子树。这里要注意的是,当我们访问到左子树时,我们把左子树当成一个新树,同时也应该满足先访问根,在访问左子树,最后访问右子树。我们发现前序遍历先访问了整个树的跟后,再把整个树左子树访问完后,再从下往上依次访问整个数的右子树。

   其实我们不难发现,当一个子树的节点为空时,我们就不再往下访问了,开始从下往上访问右子树。这好像与递归有点类似哦!其实就是用递归实现的遍历。我们结合着下图理解一下:

数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

 注:

  • 往下的箭头表示递归调用;
  • 往上的箭头表示返回,也就是归。

下面我们看代码的实现。

void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

3、2、4 中序遍历

  什么是中序遍历呢?同样,我们先来看一下比较官方的解释。

   LNR:中序遍历 (Inorder Traversal)—— 访问根结点的操作发生在遍历其左右子树的中 间。
  通俗来讲,其实就是遍历树时, 先访问左子树,再访问根,最后访问右子树。对比前序遍历,中序遍历与前序遍历大同小异,只不过是访问顺序发生了变化。我们结合这下图理解一下:
数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言

 注:

  • 往下的箭头表示递归调用;
  • 往上的箭头表示返回,也就是归。

下面我们看代码的实现。

void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	InOrder(root->left);
	printf("%c ", root->data);
	InOrder(root->right);
}

3、2、5 后序遍历

  当我们了解完前序遍历和中序遍历后,我们理解后序遍历接很简单了。 我们先看比较官方的解释。

  LRN :后序遍历 (Postorder Traversal)—— 访问根结点的操作发生在遍历其左右子树之后。
  通俗来讲,其实就是遍历树时, 先访问左子树,再右子树,最后访问根。我们直接看图:
数据结构与算法之《二叉树》详解,数据结构,算法,数据结构,树,二叉树,c语言
注:
  • 往下的箭头表示递归调用;
  • 往上的箭头表示返回,也就是归。

下面我们看代码的实现。

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%c ", root->data);
}

3、2、6 求树中节点的个数

  我们在统计树中节点的个数时,需要遍历整个树才行。当然,遍历整个树也是需要用递归的。当我们遇到某个节点为空时,我们就返回0,不是空时我们就返回1。我们结合着代码一起理解一下。 

int TreeNodeSize(BTNode* root)
{
	return root == NULL ? 0 : TreeNodeSize(root->left) + TreeNodeSize(root->right) + 1;
}

3、2、7 求树中叶节点的个数

  我们知道,叶节点的度为0,也就是叶节点的左子树和右子树均为空。同样,我们使用递归遍历整个树,遇到节点为空时返回零,遇到节点的左子树和右子树均为空返回1。我们看代码的实现。 

int TreeLeafSize(BTNode* root)
{
	if (root == 0)
		return 0;

	if (root->left == NULL && root->right == NULL)
		return 1;

	return TreeLeafSize(root->left) + TreeLeafSize(root->right);
}

3、3 二叉树的性质

  通过上面对二叉树的理解,我给大家总结出了二叉树的一些性质:

  1. 若规定根节点的层数为 1 ,则一棵非空二叉树的 i 层上最多有 2^(i-1) 个结点;
  2. 若规定根节点的层数为 1 ,则 深度为 h 的二叉树的最大结点数是 2^h- 1;
  3. 对任何一棵二叉树 , 如果度为 0 其叶结点个数为 n0, 度为 2 的分支结点个数为 n2, 则有 n0 n2 1;
  4. 若规定根节点的层数为 1 ,具有 n 个结点的满二叉树的深度 h=LogN。

  通过上面的学习,我们可以对二叉树有一个新的认识和理解,希望本编文章对您有所帮助,感谢阅读ovo! 文章来源地址https://www.toymoban.com/news/detail-788904.html

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

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

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

相关文章

  • 【算法与数据结构】深入二叉树实现超详解(全源码优化)

    上节我们学习了二叉树(前中后)序遍历 这节将实现二叉树。 让我们复习一下二叉树,接着就是二叉树的实现了😊,学习起来吧! 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总

    2024年04月11日
    浏览(74)
  • C++数据结构与算法详解:链表、栈、队列、树、二叉树和图结构的实现与应用

    链表是一种常见的数据结构由一系列节点按顺序连接而成,一般每个节点包含一个数据元素和一个指向下一个节点的引用。 链表有多种类型: 单向链表:每个节点只有一个指向下一个节点的引用 双向链表:每个节点有一个指向前一个节点和一个指向后一个节点的引用 循环链

    2024年02月04日
    浏览(47)
  • 【数据结构和算法】--- 二叉树(3)--二叉树链式结构的实现(1)

    在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,且为了方便后面的介绍,此处手动快速创建一棵简单的二叉树,快速进入二叉树操作学习,等二叉树结构了解的差不多时,我们反过头再来研

    2024年01月25日
    浏览(59)
  • 数据结构与算法-二叉树

            在计算机科学中,数据结构是组织和存储数据的基础框架,而算法则是处理这些数据的核心逻辑。在这众多的数据结构中,二叉树因其独特的层级结构、高效的搜索和插入操作,成为广泛应用的一种非线性数据结构。本文将深入探讨二叉树的定义、种类、操作方法

    2024年03月10日
    浏览(57)
  • 【数据结构与算法】—— 二叉树

    目录 一、树 1、初识树 2、树的一些概念 3、树的表示形式 二、二叉树 1、初识二叉树 2、两种特殊的二叉树 3、二叉树的性质  4、二叉树的遍历 5、实现一棵二叉树  6、二叉树题目(没代码的后面会给补上) (1)根节点没有前驱。 (2)子树的根节点只有一个前驱,可以有

    2024年04月09日
    浏览(46)
  • 数据结构---二叉树(C语言)

    空树 非空:根节点,根节点的左子树、根节点的右子树组成的。 从二叉树的定义来看,二叉树是递归定义的,因此我们可以用递归的形式来遍历二叉树。 1.1.1二叉树前中后序遍历(递归版) 访问根结点的顺序不同。 1.1.2 层序遍历 层序遍历是按照二叉树的高度,一层一层遍

    2024年02月06日
    浏览(45)
  • 数据结构:二叉树详解

    目录 概念(在做习题中常用的概念) 两种特殊的二叉树 二叉树的性质 二叉树的遍历(重点) 如上图: 二叉树的构建(代码表示一颗二叉树和一些操作二叉树的方法) 二叉树的oj习题讲解(重点) 1. 检查两棵树是否相同 力扣 2. 另一颗树的子树   力扣 3. 反转二叉树    

    2024年02月10日
    浏览(30)
  • 二叉树(上)——“数据结构与算法”

    各位CSDN的uu们好呀,好久没有更新我的数据结构与算法专栏啦,今天,小雅兰继续来更新二叉树的内容,下面,让我们进入链式二叉树的世界吧!!! 二叉树链式结构的实现  二叉树链式结构的实现 普通的二叉树的增删查改是没有价值的!!! 只有搜索二叉树的增删查改才

    2024年02月15日
    浏览(42)
  • 【数据结构】二叉树---C语言版

    树是一种 非线性 的数据结构,它是由n(n=0)个有限结点组成一个具有层次关系的集合。把它叫做树,是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点,称为根结点, 根节点没有前驱结点 除根节点外,其余结点被分成M(M0)个互不相交

    2024年02月05日
    浏览(42)
  • 二叉树--C语言实现数据结构

    本期带大家一起用C语言实现二叉树🌈🌈🌈 二叉树是一种特殊的树状数据结构,它由节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点 二叉树的链式存储结构是指用 链表 来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点

    2024年02月17日
    浏览(39)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包