目录
树和森的遍历(一般转换成二叉树,然后用二叉树的遍历方式进行遍历)
第六章:树
树是N个结点的有限集,有且仅有一个根,当N>1时,其余节点可以分为M个互不相交的子树。
结点分类
结点拥有的子树个数称为度,由此来区分结点
- 最顶层的是根结点
- 度为0的叫叶节点,终端节点
- 不为0的叫分之节点。
- 内部节点
- 树的度是所有结点中最大的那个结点的度
结点关系
- 父子关系
- parents关系
- 子孙关系
其他概念
树的每一层叫层次,最大层次是深度或者高度
树的各子树次序不能换的叫有序树,能换的是无序树
树的存储结构
事例:
双亲表示法
每个结点 = data + parent指针
孩子表示法
思考方案:
方案1:每个结点 = data + 树的度个数的子树指针
缺点:浪费空间
方案2:每个结点 = data + 当前节点度个数 + 子树指针(子链表的头指针)
缺点:结点结构不同不好处理
方案3:(孩子表示法)
每个结点的子节点放在一个单链表中 子结点 = data + next
所有的结点共同放在一个顺序存储结构(数组中) 头结点 = data + 长子指针
缺点:获取某个结点的parents需要遍历整个树
方案4:最终方案(双亲孩子表示法)
在存放所有节点的数组中加入一个parents指针,指向双亲结点
所有的结点共同放在一个顺序存储结构(数组中) 头结点 = data + parents指针+ 长子指针
孩子兄弟表示法
每个结点 = data + 长子指针 + 右兄弟指针
二叉树
二叉树是N个结点的有限集合,该集合或者为空集,或者由一个根结点和俩个互不相交的分别称为根节点的左子树和右子树的二叉树组成
特点
- 每个结点最多有俩颗子树
- 左子树和右子树是有顺序的,不能颠倒
- 只有一个子树的情况下也要区分左右
特殊二叉树
- 斜树:所有的结点头统一有一个方向的树
- 满二叉树:所有分之结点都有左右子树,所有叶结点都在同一层(最下层)
- 完全二叉树:按照层来排序,中间没有空缺的就是完全二叉树
完全二叉树
普通二叉树
二叉树的性质
- 第i层最多有
个结点
- 深度为K的二叉树最多有
个结点
- 终端结点数 = 度为2的结点数 + 1
- n个结点的完全二叉树的深度为
二叉树的存储结构
顺序存储结构
一般只用于完全二叉树,由于完全二叉树结构固定所以可以用顺序存储结构存储
下标代表序号
二叉链表
每个结点 = 左孩子指针 + data + 右孩子指针
遍历二叉树
二叉树的遍历是指从根节点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次。
遍历方法
1.前序遍历:如果二叉树为空,则空操作返回,否则先访问根节点,然后前序遍历左子树,再前序遍历右子树
2.中序遍历
3.后序遍历
4.层次遍历
性质:
- 已知前序遍历序列和中序遍历序列,可以唯一确定一颗二叉树
- 已知后序和中序遍历顺序,可以唯一确定一颗二叉树
二叉树的建立
把二叉树中每个节点的空指针引出一个虚节点,值为一个特定值#,这叫做扩展二叉树
线索二叉树
在二叉链表中有很多空的指针域,为了利用这些指针域可以把他指向他的前驱(左)或者后继(右),这样就形成了线索
把指向前驱和后继的指针称为线索,加上线索的二叉链表称为线索链表,相应的二叉树称为线索二叉树
对二叉树以某种次序遍历使其变为线索二叉树的过程称作线索化
此时已经利用上了空闲的指针域,但是引入了新的问题,这个指针域是指向子节点还是前驱或者后继,所以需要加一个标志位
线索化的实质,就是把二叉链表中的空指针改为指向前驱或者后继的线索。
线索化的过程就是在遍历的过程中修改空指针的过程
树,森,二叉树的转换
树转换为二叉树
森转换为二叉树
二叉树转换为树
二叉树转换为森
树和森的遍历(一般转换成二叉树,然后用二叉树的遍历方式进行遍历)
树的遍历:
- 先根遍历
- 后根遍历
森的遍历
- 前序遍历
- 后序遍历
赫夫曼树
路径长度:从树中一个结点到另一个结点之间的分支构成俩个节点之间的路径,路径上的分支数目就叫做路径长度
树的路径长度:根到每个节点路径长度之和
结点的带权路径长度:从该节点到根之间的路径长度与结点上权的乘积
树的带权路径长度:树种所有叶节点带权路径长度之和。
带权路径长度最小的二叉树称作赫夫曼树,最优二叉树
赫夫曼树的构造方法
赫夫曼编码的应用
用于文件压缩,字节压缩,思想理解