【数据结构——树和森林】

一、树的存储结构

(一)双亲表示法

实现: 定义结构数组来存储树的结点,每个结点含有两个域:
在这里插入图片描述数据域:存放结点本身信息
双亲域:指示本结点的双亲结点在数组中的位置

特点: 找双亲容易,找孩子难

在这里插入图片描述


#define MAX_TREE_SIZE 100
typedef struct PTNode
{
    
    //结点结构
	ElemType data;
	int parent;//保存双亲位置
}PTNode;

typedef struct
{
    
    //定义树结构
	PTNode nodes[MAX_TREE_SIZE];
	int r, n;//根的位置和结点数
}PTree;

(二)孩子链表表示法(带双亲的孩子链表-parent)

在这里插入图片描述

//孩子链表表示法的类型描述
typedef struct CTNode
{
    
    
	int child;
	struct CTNode* nextchild;
}*ChildPtr;
//双亲结点结构
typedef struct
{
    
    
	ElemType data;
	int parent;//保存双亲位置
	ChildPtr firstchild;//孩子链的头指针
}CTBox;
//树结构
typedef struct
{
    
    
	CTBox nodes[MAX_TREE_SIZE];
	int n, r;//结点数和根结点的位置
}CTree;

(三)树的二叉链表(孩子-兄弟)存储表示法

在这里插入图片描述

在这里插入图片描述

/*树的二叉链表类型描述*/
typedef struct CSNode
{
    
    
	ElemType data;
	struct CSNode* firstchild, * nextsibling;
}CSNode,*CSTree;

二、森林与二叉树的转换

(一)将树转换成二叉树

加线: 在兄弟之间加一条连线
抹线: 对每个结点,除了其最左边孩子外,去除其与其余孩子之间的关系
旋转: 以树的根结点为轴心,将整树顺时针旋转45度。

在这里插入图片描述
树转换成的二叉树,根结点的右子树一定为空

(二)将二叉树转换成树

加线: 若p结点是双亲结点的左孩子,则将P的右孩子,右孩子的右孩子·····沿着分支找到的所有右孩子,都与p的双亲用线连起来
抹线: 抹掉原二叉树中双亲与右孩子之间的连线
调整: 将结点按层次排列,形成树的结构
在这里插入图片描述

(三)将森林转换成二叉树

1、将各棵树分别转换成二叉树
2、将每棵树的根结点用线连接起来
3、以第一棵树的根结点为二叉树的根,再以根结点为核心,顺时针旋转,构成二叉树形结构

在这里插入图片描述

(四)将二叉树转换成森林

抹线: 将二叉树中根结点与其右孩子连线,以及沿右分支搜索到的所有右孩子间连线全部抹掉,使之变成孤立二叉树
还原: 将孤立的二叉树还原成树
在这里插入图片描述

三、树和森林的遍历

遍历: 按照一定规律走遍树的各个顶点,且使每个顶点仅被访问一次,即找一个完整而有规律的走法,以得到树中所有结点的一个线性排列

(一)树的遍历(不讨论中序)

常用方法:
1、先根(序)遍历:先访问树的根结点,然后依次先根遍历根的每棵子树
2、后根(序)遍历:先依次后根遍历每棵子树,然后访问根结点
3、按层次遍历:先访问第一层上的结点,然后依次遍历第二层,·····,第N层的结点。

在这里插入图片描述

(二)森林的遍历(不讨论后序)

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_46518461/article/details/109395052
今日推荐