【Day10·超详细】数据结构 之 树和森林

导读

本篇文章将会介绍树的三种存储方式(双亲表示(顺序)、孩子表示(顺序+链式)、孩子兄弟表示法(链式))、二叉树和森林的转换、树和森林的遍历,并会给出完整的伪代码供读者参考

树的三种表示方法

对于二叉树,我们最常用的是二叉链表,但对于普通的树,每一个结点可以有多个孩子,在此有三章方法去表示,下面将一一介绍:

1.双亲表示法:

typedef struct PTNode{
	char data;
	int parents;
}PTNode; 
typedef struct{
	PTNode nodes[MAXSIZE];
	int n;//结点数 
}*PTree;

这种表示方法实际上就是一个结构体数组,每一个元素中包含了两个成员,一个是char型,存储数据内容,一个是int型,保存双亲的序号,如上图所示。

2.孩子表示法

孩子表示法是一种顺序存储与链式存储相结合的存储方式,如下图所示:

 首先我们定义孩子结点CTNode:

typedef struct CTNode{
	int child;
	struct CTNode* next; 
}CTNode; //孩子结点 

再定义每一个元素的“块”:

typedef struct{
	char data;
	CTNode *firstchild;
}CTBox;

最后定义整个树:

typedef struct{
	CTBox nodes[MAXSIZE];
	int n,r;
}CTree;

3.孩子兄弟表示法:

typedef struct CSTNode{
	char data;
	struct CSTNode *firstchild,*nextsibling;
}CSTNode,*CSTree; 

二叉树和森林转换

森林就是一个及一个以上的树组成的集合,这些树不一定是二叉树

森林转换成二叉树步骤:

1.把森林中每一棵树转换为二叉树

2.将这几棵树的头结点依次相连,右边相邻的为左边的右子树

举例:

二叉树到森林就是一个逆过程

树和森林的遍历 

对于树的遍历,仅分为两种,先根和后根遍历

以先根为例讲解(后根自己类比)

先根就是先访问根结点,然后依次对子树访问:

比如,对于:

                  a

    b             c           d

  e   f         g           h    i

j               k

的先根遍历为a b e j f c g k d h i

实现思路最简单的还是使用递归

大体思路如下:

void PreOrder(Tree T)
{
	if(!T)
	{
		visit(T);
		while(T还有子树)
		PreOrder(T); 
	}
}

至于子树的寻找,与存储方式有关,在这里面,当然是孩子链表方法比较简单,但下面我将以孩子兄弟表示为例,分享一下我的思路:

首先我想附设一个函数

CSTree nextchild(int i,CSTree T)

这个函数返回结点T的子树,i表示第几棵子树,完整代码如下:

void PreOrder(CSTree T)
{
	int i=1;
	if(!T)
	{
		visit(T);
		while(nextchild(i,T))
	    {
	    	PreOrder(nextchild(i,T));
	    	i++;
		}
    } 
} 

CSTree nextchild(int i,CSTree T)
{
	if(i==1)
	return T->firstchild;
	T=T->firstchild;
	while(i-1)
	{
		T=T->nextsibling;
		i--;
	}
	return T;
}

最后看森林遍历,森林分成三个部分:

第一棵树的根节点

第一棵树的子树

除第一棵树的其它树

由此分成了先序和中序遍历

先序:

先访问第一个树根节点再第一棵树的子树再除第一棵树的其它树

相当于对每一棵树先序遍历

中序

先访问第一棵树的子树再第一棵树的根节点再除第一棵树的其它树

相当于对每一棵树后序遍历

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值