【C语言】树和二叉树的基本概念和实现

前言

在生活中有很多关于树和二叉树的例子,我们对文件进行操作的时候,文件系统就是利用了目录树结构而实现的。今天我们来学习树和二叉树的概率以及实现。

       

目录

前言

树的概念及结构

树的概念

树的结构表示

二叉树的概念及结构

二叉树的概念

二叉树链式结构的实现

二叉树链式结构的遍历

前序遍历的实现

中序遍历的实现

后序遍历的实现


树的概念及结构

树的概念

  树是一种非线性 的数据结构,它是由 n n>=0 )个有限结点组成一个具有层次关系的集合。把它
叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
树有一个特殊的结点,称为根结点,根节点没有前驱结点
除根节点外,其余结点被分成M(M>0) 个互不相交的集合 T1 T2 …… Tm,其中每一个集
合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以
0个或多个后继
因此,树是递归定义的。 
              
重要!!!
  节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A 的为2,B的为3.
叶节点或终端节点:度为0 的节点称为叶节点; 如上图:D E F G 等节点为叶节点
非终端节点或分支节点:度不为0 的节点; 如上图:B C 节点为分支节点
双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点; 如上图:A 是B
的父节点
孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B A的孩子节
兄弟节点:具有相同父节点的节点互称为兄弟节点; 如上图:B C是兄弟节点
树的度:一棵树中,最大的节点的度称为树的度; 如上图:树的度为3
节点的层次:从根开始定义起,根为第1 层,根的子节点为第 2层,以此类推;
树的高度或深度:树中节点的最大层次; 如上图:树的高度为3
节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先
  子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙
森林:由m m>0)棵互不相交的多颗树的集合称为森林;(数据结构中的学习并查集本质就是
一个森林)   

树的结构表示

树结构相对线性表就比较复杂了,要存储表示起来就比较麻烦了,实际中树有很多种表示方式,
如:双亲表示法,孩子表示法、孩子兄弟表示法等等。我们这里就简单的了解其中最常用的孩子
兄弟表示法
typedef int NodeDate;
struct Node
{
	struct Node* FirstChild1;//第一个孩子结点
	struct Node* NextBrother;//指向其下一个兄弟结点
	NodeDate val;            //节点中的数据
};

下面是兄弟表示法的具体流程,当知道第一个孩子结点,将这个孩子指向他的下一个兄弟结点,这样树的整体结构就能够串联起来。

                     

二叉树的概念及结构

二叉树的概念

一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根节点加上两棵别称为左子
树和右子树的二叉树组成。
二叉树的特点:
1. 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
2. 二叉树的子树有左右之分,其子树的次序不能颠倒。

       

二叉树链式结构的实现

二叉树链式结构的遍历

所谓遍历 (Traversal) 是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访
问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行
其它运算之基础。
前序/中序/后序的递归结构遍历:是根据访问结点操作发生位置命名
1. NLR:前序遍历(Preorder Traversal 亦称先序遍历)——访问根结点的操作发生在遍历其左右
子树之前。
2. LNR:中序遍历(Inorder Traversal)——访问根结点的操作发生在遍历其左右子树之中
(间)。
3. LRN:后序遍历(Postorder Traversal)——访问根结点的操作发生在遍历其左右子树之后。
由于被访问的结点必是某子树的根,所以N(Node)、L(Left subtree)和R(Right subtree)又
可解释为根、根的左子树和根的右子树NLRLNRLRN分别又称为先根遍历、中根遍历和后根 遍历
前序遍历的实现

前序遍历的遍历顺序是,根->左子树->右子树。

                                      

从图中可以看出最后遍历出数据的顺序是A B D G H C E I F。

仔细观察可以发现,这种图类似与递归算法。所以在实现二叉树的遍历时可以用递归算法来实现。

void PrevOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;
	}
	printf("%d", root->val);
	PrevOrder(root->Left);
	PrevOrder(root->Right);
}
中序遍历的实现

中序遍历的遍历顺序是,左子树->根->右子树。

                                   

从图中可以看出最后遍历出数据的顺序是G D H B A E I C F。

同样我们利用递归算法来实现它。

void InOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;
	}
	InOrder(root->Left);
	printf("%d", root->val);
	InOrder(root->Right);

}
后序遍历的实现

中序遍历的遍历顺序是,左子树->右子树>根。

                                  

从图中可以看出最后遍历出数据的顺序是G H D B A I E F C 。

同样我们利用递归算法来实现它。

void PostOrder(BTNode* root)
{
	if (root == NULL)
	{
		printf("NULL");
		return;
	}
	PostOrder(root->Left);
	PostOrder(root->Right);
	printf("%d", root->val);

}

好啦,这就是今天学习的分享啦!看到希望大家的三连呀!

如果有不当之处,欢迎大佬指正!

  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值