线性表 链表 栈 串 这些都是一对一关系的线性结构
下面讨论一对多的关系
树
一些概念:
只能有一个根节点,可以有很多子节点,但子节点之间不能相交
一个结点有几个子节点称为几度
度为0 的结点叫 叶结点 或 终端节点
整个树的度是所有结点度的最大值
结点最大的层次称为树的深度
如果把树的结点从左至右看成是有序的,不能互换的,称为有序树
树的存储结构:
双亲表示法
每个结点分为两部分 一部分存储该节点的信息,另一部分存储到双亲的指针(双亲的数组下标)
这样的话 想知道双亲容易 想知道孩子 就得遍历整个树
孩子表示法
每个结点有多个指针域,每个指针分别指向一颗子树的根节点(多重链表表示法)
方案一:每个结点的指针域数量等于树的度
浪费空间
方案二:每个结点的指针域数量等于该结点的度,专门用一个位置(度域)存储该结点 的度
运算消耗时间
综合方案:
把每个结点的孩子存储在一个单链表里,再把每个节点的头指针顺序存储在一个线性表中
这样的话就有两种结点
一种是单链表的结点 两部分组成 数据域存储该结点在线性表中的位置信息,指针域存储下一个孩子结点的指针
另一种是线性表的结点 数据域存储该结点的数据信息,指针域存储该节点孩子链表的头指针
问题:找双亲需要遍历整个树
改进:双亲孩子表示法
在线性表中加入一个区域存储双亲的指针
孩子兄弟表示法:
(二叉树)
任意一棵树, 它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。
因此,我们设置两个指针, 分别指向该结点的第一个孩子和此结点的右兄弟。
结点三部分组成
数据域 第一个孩子指针 右兄弟指针
二叉树
对于这种在某个阶段都是两种结果的情形,比如开和关、0 和1 、真和假、上和下、对与错,正面与反面等, 都适合用树状结构来建
模,而这种树是一种很特殊的树状结构,叫做二叉树。
特点:
二叉树结点的度最大为2
左右不能颠倒 是有序的
某结点只有一颗子树也有区分左右
几种特殊的二叉树
斜树 只有左子树或右子树
满二叉树 所有结点都分别有左子树和右子树 并且 所有叶子都在同一层
完全二叉树 每个结点按照满二叉树的结构逐层顺序编号,如果编号出现空挡,就说明不是完全二叉树,否则就是。
二叉树的性质
二叉树第i层最多有2的i-1次幂个结点
深度为k的二叉树最多有2的k次幂-1个结点
任何一棵二叉树T,如果其终端结点数为m,度为2 的结点数为n,m=n+1
具有n 个结点的完全二叉树的深度为 log2 n + 1,i=1为根,2i>n没有左孩子否则左孩子是2i,2i+1>n没有右孩子否则右孩子是2i+1
二叉链表
每个结点三个部分组成 左孩子指针 数据域 右孩子指针
二叉树遍历
前序遍历 先访问根节点 ,然后前序遍历左子树 再前序遍历右子树 (根 左 右)
中序遍历 先中序遍历左子树 直到为空返回根节点 然后中序遍历右子树 注意 不是先访问根节点 (左 根 右)
后序遍历 从左到右先叶子后结点的方式遍历左右子树 然后访问根节点(左 右 根)
层序遍历 略
注意:已知前序和后序遍历,是不能确定一棵二叉树的
线索二叉树
线索化的实质就是将二叉链表中的空指针改为指向前驱或后继的线索。由于前驱
和后继的信息只有在遍历该二叉树时才能得到,所以线索化的过程就是在遍历的过程中修改窒指针的过程。
这时二叉树就转换成了一个双向链表