第一部分 --- 树和森林
这些互不相交的有限集就称为树的子树
1.把树的根结点去掉的话我们就能得到森林,给森林加上根结点的话我们就得到一棵树
1.规定:根结点的双亲域为 -1,遇到 - 1的时候就表示这个结点没有双亲
1.除了存储数组以外,我们还要额外存储两个数据,一个是根结点在数组中的下标 r,还有一个是数组中的结点总数 n
1.找结点双亲容易:直接通过双亲域找到,找孩子难:找一个结点A的孩子还得遍历数组找到所有双亲域指向结点A的结点元素才行
1.如果一个结点的孩子链表为空表的话,则指向这个孩子链表的首结点的头指针也为空
2.孩子链表中的结点的数据域存储的是对应结点在数组中的下标,指针域指向的是下一个孩子(按照从左到右的顺序排列的)
3.我们创建的数组中存放的是树中的双亲结点,其中数组的元素都是结构元素,由两个域组成,一个数据域存储的是树的双亲结点中存储的数据信息,还有一个指针域中存放的是指向树的双亲结点的孩子链表的首结点的头指针
(由于树的每一个结点都能够成为双亲结点,所以树的每一个结点都要存在数组中)
1.除了存储数组以外,我们还要存储两个信息,一个是根结点在数组中的下标 r (整型),还有一个是数组存放的结点总数 n (整型)
2.这种存储方式就是找一个结点的孩子容易(直接看孩子链表),但是找一个结点的双亲难
比如找某个结点A的双亲,我们必须遍历数组中的每一个元素的孩子链表(除结点自身以外),直到找到一个孩子链表中存在一个结点,这个结点的数据域中存放的是结点A在数组中的下标,此时拥有这个孩子链表的元素就是结点A的双亲结点
还有一种通过消耗空间来缩短时间的方式,使得我们找孩子容易找双亲也容易,那就是在上面的数组中给每一个元素再增加一个数据域,这个数据域中存放的是结点的双亲结点在数组中的下标
我们称这种结构为 : “带双亲的孩子链表”
1.排序方式是从左往右排
2.二叉链表 / 二叉树链表:链表中的元素具有两个指针域和一个数据域,如果存储的是二叉树的话,则两个指针域分别指向结点的左孩子和右孩子
3.对于孩子兄弟表示法而言,这两个指针域分别指向结点的第一个孩子和结点的下一个兄弟(排序方式是从左往右排)
这种存储方式找孩子和兄弟容易,找双亲难(如果想变简单的话我们可以采取消耗空间换取时间的方式,给每一个结点再增加一个指针域,让这个指针域指向结点的双亲结点)
1.将树转化为与其等价的二叉树,然后对二叉树进行各类操作和运算(更容易实现且更简单)就相操作完后再将二叉树转换为树,我们就能够得到进行对应操作后的树了
2.树的二叉链表存储方式就是:孩子兄弟链表(一个指针域指向结点的第一个孩子,另一个指针域指向结点的下一个兄弟)
将树以孩子兄弟链表的方式存储到内存空间中,而孩子兄弟链表又是以二叉链的形式形成的,二叉链的形式形成的链表由可以映射为一个二叉树,我们存储的树对应的二叉树就是映射出的这一棵
将一棵树转换为对应的二叉树的方式:
1.每一个结点都和其兄弟结点相连(注意区分堂兄弟和兄弟,兄弟是在同一棵树且同一层中的结点,而堂兄弟则是在同一层但是在不同棵树中的结点)
2.每一个结点只保留和左孩子的连线,与其他孩子的连线全都删除掉
3.第三步可以理解为将树中除根结点外的所有部分相对其原位置顺时针旋转45°后得到原来的树对应的二叉树
将二叉树转换为树的话就是将树转换为二叉树的步骤反着执行
1.这里的二叉树排序是按照从左往右的顺序由小到大排
2.这里的顺时针旋转依然是将除根结点外的所有部分相对其原来的位置顺时针旋转45°
1.先删除掉根结点与其右孩子,其右孩子与其右孩子的右孩子....之间的连线
2.将得到的多个孤立的二叉树还原为树,这些树组成的森林就是我们原来的二叉树对应的森林
3.树中的结点的孩子是没有左右孩子之分的,所以一个结点如果只有一个孩子的话,这个孩子可以直接处于结点的正下方
1.二叉树的遍历有四种方式:先序(根)遍历,中序遍历,后序遍历和层次遍历(按照二叉树的层由上往下遍历,然后每一层按照从左往右的顺序遍历)
树的遍历方式中没有中根(序)遍历的原因是树的一个结点可能有大于两个子树,此时进行一次中根遍历是无法遍历完所有子树的(中根遍历的顺序是子树1 -> 根结点 -> 子树2),如果结点有奇数个子树的话,我们用中根遍历的方式来进行遍历就会导致时间的浪费(有一个子树要被重复遍历两次,根结点也会被重复遍历多次)
综上我们舍弃了树的中根遍历方式,选择了先根遍历,后根遍历以及层次遍历(这三种方法可以保证每一个结点都只被遍历一次)
1.在进行森林的遍历之前我们将森林分为三个部分:分别是一.森林中第一棵树的根结点;二.森林中第一棵树的子树森林;三.森林中其它树构成的森林
这三个部分分别对应的树的根结点,根结点的左子树和右子树
我们一般将森林的遍历分为两种方式:先序遍历(先遍历第一颗树的根结点,然后是第一棵树的子树森林,然后是其它树组成的森林),中序遍历(先遍历第一棵树的根结点下的子树森林,然后遍历第一棵树的根结点,然后再遍历其它树组成的森林)