数据结构——树

本文详细介绍了树的基本概念,包括节点层次、高度定义、森林与单树的区别,重点讲解了树的表示方法,如指针数组、顺序表和左孩子右兄弟表示法,并探讨了实际应用,如文件目录结构。还涵盖了树的两种表示法——层次表示和双亲表示法,以及它们在操作系统中的体现。
摘要由CSDN通过智能技术生成

树的基本概念

树是一种非线性的数据结构,因它的结构与倒着的树类似而得名。

树由N个节点构成,其中最上面有一个根节点,其它的节点可以认为都是根节点的孩子。

既然是倒过来的树,那么上图的A节点就相当于根,往下伸展最下面的就是叶子。

树有N个节点,又是由多个结构相同的子树组成的,像上图:

 每个子树的根节点只能有一个前驱,可以有多个后驱(也可以没有)。

 并且子树之间不能有交集,否则就不是树形结构,而是另一种数据结构:图。

 像红线这里,产生了交集,这就不是树,而是图了。

下面列举了树结构里面一些常见的概念:

 关于这里节点的层次、树的高度说明一下:

有的书上定义层次时,将根节点A(最上面的根节点)层次定义为1,但也有的定义为0,这是两种不同的定义方式,我个人认为起始层次定义为1更好一点(原因如下)

 森林是由多棵树构成的,像并查集就是森林。

树的表示

要写一个树的结构就不像顺序表和链表那么简单了,因为它不是线性的,不能顺着一条线访问。

而且节点个数不确定,这样在构造结构的时候就会比较麻烦。

 像这样不知道有多少个节点不好下手,这时我们想到可以用指针数组来封装节点。

 用一个childArr封装节点,并用childSize记录节点个数。但是这相当于是静态的树,因为它把树的度给定死了,有的节点的度是50,但有的可能只有2,就会有很多浪费,无法满足我们的需求。这时候就需要动态的。

 再用一个顺序表来存节点,需要用到二级指针,但这种结构虽然直观了一点,但是在C语言中很复杂,如果是在C++下面上个容器会清楚很多,但也不是最优的,有高手就创造了一种很好的结构(左孩子右兄弟表示法)。

 

 

 让根节点去找它的第一个子节点,让第一个子节点去找它的兄弟节点。相当于一个爹先养一个大儿,大儿再养二儿.......这样就可以找到全部节点了。

有人可能会问,不是不能有交集吗?注意:这里是实现方式,实现方式可以任意,但是结构是不能产生交集的。我这么实现,但是结构出来是没有交集的。

下面是一段打印整个树的伪代码:

typedef struct TreeNode
{
	struct TreeNode* child;
	struct TreeNode* brother;
	int data;
}TreeNode;

void TreeNodePrint(TreeNode* parent)
{
	if (parent == NULL)
		return;
	TreeNode* cur = parent->child;//找到第一个孩子
	while (parent)
	{
		//printf(); 打印数据
		TreeNodePrint(parent);//递归调用,打印整个树
		cur = cur->brother;
	}
}

数还有一种表示法,叫双亲表示法。这种方式方便任何节点找祖先,像之前说的并查集就是这种表示法。

 

树的实际应用

像我们操作系统文件目录什么的就是树来实现的。

 当我们点list这个文件夹时,就类似执行上面那种伪代码(只是类似),然后就显示下一层(子节点)。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值