250 likes | 387 Views
树的查找和树的应用. 上海金融学院信息管理系. 第六章 树的查找和树的应用. 6.1 查找树 6.2 满树、拟满树和丰满树 6.3 堆和堆排序. 6.1 查找树. 前面介绍 : 顺序查找、二分查找、分块查找、 HASH 查找。 二分查找法,操作速度快,但要求结点序列顺序存储(存放在数组中)。 结点序列存放在数组中,插入和删除需要移动大量结点,很不方便。 这里介绍既可用二分查找,又使用方便插入和删除的链接存储的方法 —— 查找树。. 6.1 查找树. 1 . 查找树的定义
E N D
树的查找和树的应用 上海金融学院信息管理系
第六章 树的查找和树的应用 6.1 查找树 6.2 满树、拟满树和丰满树 6.3 堆和堆排序
6.1 查找树 前面介绍:顺序查找、二分查找、分块查找、HASH查找。 二分查找法,操作速度快,但要求结点序列顺序存储(存放在数组中)。 结点序列存放在数组中,插入和删除需要移动大量结点,很不方便。 这里介绍既可用二分查找,又使用方便插入和删除的链接存储的方法——查找树。
6.1 查找树 1. 查找树的定义 查找树T是一棵二叉树,要么为空,要么满足下面三个条件: (1)如果树T的根结点的左子树非空,那么左子树中的所有结点的键值都小于T的根结点的键值; (2)如果树T的根结点的右子树非空,那么右子树中的所有结点的键值都大于T的根结点的键值; (3)它的左、右子树都是查找树。
6.1 查找树 2. 性质 二叉树T为查找树的充分必要条件是,按中序遍历二叉树T的结点可得到已排好序的结点序列。 p. 146 图6.1.1 画出4棵查找树
6.1 查找树 3. 二叉查找算法 在给定的查找树t中找出具有给定键值a的结点的算法。 (1)如果t为空,那么查找失败,算法结束;否则,进入(2); (2)如果t->data等于a,那么查找成功,算法结束;否则,进入(3); (3)如果a小于t->data,那么t=t->lchild;否则,t=t->rchild。转到(1)。 p. 147 search(t, a, p_p, p_q)
3. 二叉查找算法 分析算法search(t, a, p_p, p_q) *p_q 是指针,指向当前结点 *p_p 是指针,指向当前结点的父结点 算法执行到结束,若*p_q不空,则*p_q所指的结点就是a结点(找到了),而*p_p指向它的父结点。假若*p_p为空,则a结点就是根结点。 假若*p_q为空,则表示找不到a结点。这时考察*p_p,若为空,则查找树t为空树;否则,*p_p指向查找路径的最后一个结点。 记住以上分析,有利于解决以后问题。
6.1 查找树 4. 在查找树中插入结点的算法 在给定的查找树t中插入一个键值为a 的结点,首先调用函数search( ),查找结点a。如果它在树t中,则不做插入,返回1;否则把它插到查找树t的合适位置上,返回0。 pp. insert(p_t, a)
6.1 查找树 5. 在查找树中删除结点的算法 要求: 找到要删除的结点,将它删去,但操作以后的二叉树仍是一棵查找树。 原则: 若被删结点有左子树,那么被删结点的位置由它的左子树的根结点来充当,它的右子树被链接在左子树的最右下方;否则,被删结点的位置由它的右子树的根结点来充当。
5. 在查找树中删除结点的算法 分六种情况分析: (1)若被删的是根,而且 ①它没有左子结点 ②它有左子结点 (2)若被删结点非根,且没有左子结点 ③被删结点是父结点的左子结点 ④被删结点是父结点的右子结点 (3)若被删结点非根,且有左子结点 ⑤被删结点是父结点的左子结点 ⑥被删结点是父结点的右子结点
5. 在查找树中删除结点的算法 pp. 149-150 delete(p_t, a) 删除成功,则返回0;否则,返回1。 以上算法不是唯一的。也有其他算法,只要保持被删除结点后仍然是查找树就行。
6.2 满树、拟满树和丰满树 要使查找时间小,则应使从根到其他结点的树枝尽量地短。也就是说,各结点应安排在尽量靠近根的位置。
1. 满树、拟满树和丰满树的定义 设二叉树T有n个结点,令i=[log2(n+1)],r=n-(2i-1)。如果其中(2i-1)个结点放满第0至第(i-1)层。 (1)若r=0,则称树T是一棵满二叉树,简称满树。 (2)若r>0,且剩下的r个结点靠左开始排列在第i层上,则称树T是一棵拟满二叉树,简称拟满树。 (3)若r>0,且剩下的r个结点随意地分布在第i层上,则称树T是一棵丰满二叉树,简称丰满树。(p. 152 图6.2.1)
2.满查找树、拟满查找树和丰满查找树 若树T是一棵满树,同时又是查找树,则称树T是一棵满查找树。 若树T是一棵拟满树,同时又是查找树,则称树T是一棵拟满查找树。 若树T是一棵丰满树,同时又是查找树,则称树T是一棵丰满查找树。 性质: 满查找树 => 拟满查找树 => 丰满查找树
3. 构造丰满树 设有n个结点的任意序列,可用平分法构造出相应的丰满树。具体做法: (1)如果结点序列为空,那么得到一棵空的二叉树。 (2)如果序列中有n(≥1)个结点k0, k1, …, kn-1,那么令m=[(n-1)/2],所求的树是有根结点km,以及它的左子树Tl和右子树Tr所组成,其中Tl和Tr分别是用平分法由k0, k1, …, km-1和km+1, km+2, …, kn-1得到的丰满树。
3. 构造丰满树 上面方法构造的丰满树,有性质: (1)若丰满树T中有n个结点,则树T有[log2n]+1层。 (2)如果构造前的结点序列是有序的,则得到的丰满树是一棵丰满查找树。 p. 153 图6.2.2 丰满查找树
6.3 堆和堆排序 1. 堆(heap)的定义 设二叉树T是一棵拟满树,且树中的任一结点的值不小于它的左子结点(如果左子结点存在)和右子结点(如果右子结点存在)的值,则称树T是一个堆。
6.3 堆和堆排序 2. 堆的存储结构 具有n个结点的堆T,可按层次序将结点存放在数组a[ ]中。由于堆也是拟满树,那么它具有拟满树按层次序进行顺序存储的性质: 若对于i≥0,有2*i+1<n,则a[2*i+1]是a[i]的左子结点,且a[i] ≥a[2*i+1]; 若对于i≥0,有2*i+2<n,则a[2*i+2]是a[i]的右子结点,且a[i] ≥a[2*i+2]。 显然,结点a[0]的值是最大的。
6.3 堆和堆排序 3. 堆排序 原理: 假如需要排序的n个结点形成了一个堆,存储在数组a[ ]中,那么结点a[0]的值为最大。将a[0]与a[n-1]对调,即最大的结点换到a[n-1]中。 剩下的a[0], a[1], …, a[n-2]这n-1个结点就不再继续成为堆了。现进行调整使其成为堆,那么a[0]的值在余下的结点中为最大。将a[0]与a[n-2]对调,然后再在剩下结点中加以调整,使之成为堆……如此对调、调整,直到排序完成。
3. 堆排序 算法设计: (1)调整成为堆的算法 对于一棵具有n个结点的顺序存储在数组a[ ]中的拟满树,根结点的左、右子树都是堆,但根结点a[0]不满足堆的条件。要求将这棵拟满树调整成为堆。 具体做法是将左、右子树中值最大的结点移到根结点的位置上来,而将原来的a[0]调整到其合适的位置上去。 pp. 154-155 siftdown ( a, i, n) a:数组;i:根结点下标;n:调整范围
3. 堆排序 (2)堆排序的算法 对n个结点的序列(存放在数组a[ ]),反复调用函数siftdown( ) ,由最小的子树开始,从小到大将其调整成为堆。 反复执行:将堆的根结点对调换到后面去,然后将剩余结点调整成为堆。 p. 155 heap_sort(a, n)
复习 • 简单的时间复杂度的计算 • 表的顺序存储与链接存储的方法、特点与不足 • 栈与队列,尤其是链接栈与链接队列 • 扩展链表(如环形双向链表)的插入/删除结点的算法 • 各种排序方法(插入、选择、冒泡、快速、希尔、合并等)的做法;若序列是链接存储的情况,插入、选择等排序的算法
复习 6. 三元组数组表示的稀疏矩阵 7.n次树与二叉树的转换 8. 前、中、后、层次遍历二叉树的做法 • 按前序顺序存储二叉树(左标志右下标/两个标志)与标准形式存储二叉树的转换 • 中序遍历二叉树的算法 • 穿线树的操作和穿线排序的算法 • 查找树结点的查找、插入和删除的算法
复习 • 用递归方法来解决有关广义表和二叉树的问题的算法 如复制一个广义表,判断两个广义表是否相等,复制一棵二叉树,遍历一棵二叉树,将一棵二叉树左右对换(旋转1800),统计树中的结点数、层次数、树枝长度等
复习 14. 简单内容 (1)表达式中缀与后缀的转换 (2)模式失败链接值 (3)字符串相等的定义 (4)常用算法(如加表头)的作用