停更了三天,补番去了(颓废)
1.树与森林简介
树状图是一种数据结构,它是由n(n>=1)个有限结点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结点可以分为多个不相交的子树;(百度百科)
特别注意的是,除根节点外,每个节点有且仅有一个双亲结点。
森林是n棵互不相交的树。
2.树的存储
- 双亲表示法
通过数组表示,数组中每一个位置有两个元素,分别是自身的值与双亲结点的下标,如图所示:
- 孩子链表表示法
用一个数组来存放二叉链表的结点,数组元素包含结点自身的值和一个链表的头,这个链表由它所有的孩子串在一起构成。如图所示:
- 孩子兄弟表示法(树转化为二叉树)
每个结点由两个指针域与数据域组成,左指针域指向第一个孩子,右指针域指向它的右邻兄弟。具体转化方法:连接兄弟节点(同一层),再擦除除了父节点与长子节点之外的所有父节点与子节点的连接,如图所示:
3.森林与二叉树的相互转换
- 森林转换为二叉树
先将森林中的每棵树分别转为二叉树,再将除第一个外的每一个二叉树的根节点连接头一棵树的根节点作为右孩子,如图:
- 二叉树转换为森林
先将各节点与其左孩子的所有右后代(右孩子,右孙子)连接,再擦书原图中所有与右孩子的连接,整理。如图所示:
4.树的遍历
- 先根遍历
先根遍历即先访问书的根节点,再访问子树。对其所对应的二叉树进行先序遍历即可。 - 后根遍历
先遍历子节点再遍历根节点。对其所对应的二叉树进行中序遍历即可。 - 层序遍历
逐层遍历。对数进行根节点开始的广度优先遍历即可。 - 遍历图示
如图所示树:
5.树与森林的C++实现
由于双亲存储与孩子链表存储的树的有关操作与图的有关操作类似,树的孩子兄弟存储有关操作与二叉树类似,树的层序遍历本质为BFS,此处仅提供双亲存储与孩子链表表示法的类型代码。
- 树的双亲存储
template <class T>
struct tree_node{T data; int parent;};
template <class T>
class tree
{
public:
tree();
~tree();
// void create();
// BiTree<T> tran();
// lev();
private:
tree_node<T> tree_arr[maxn];
int node_num;
};
- 树的孩子链表表示法
struct node{int loc; node* next;};
template <class T>
struct tree_node
{
T data; //存数据
node* next; //指向链表
};
template <class T>
class tree
{
public:
tree();
~tree();
// void create();
// BiTree<T> tran();
// lev();
private:
tree_node<T> tree_arr[maxn];
int node_num;
};
相关博文请参考:
二叉树:传送门
BFS:传送门(未写)
图的存储:传送门(未写)
总提纲: 《数据结构》期末提纲小结