270 likes | 364 Views
查找和排序. ---- 动态查找,二叉树篇. 二叉排序(查找)树. 定义 若二叉树不空,则 若它的左子树不空,则左子树上所有结点的值均小于根结点的值,且是一棵二叉树; 若它的右子树不空,则右子树上所有结点的值均大于根结点的值,且是一棵二叉树;. 二叉排序树中查找的过程. 查找51,33 与根结点进行比较, 如果和根结点的值相等,则找到了; 如果比根结点的值大,则到右子树中查找;否则,到左子树中查找. 二叉排序树插入. 将 31 插入到右边的二叉排序树中 先找到要插入的位置(查找过程) 将 31 插入到合适的位置. 二叉排序树删除.
E N D
查找和排序 ----动态查找,二叉树篇
二叉排序(查找)树 • 定义 若二叉树不空,则 • 若它的左子树不空,则左子树上所有结点的值均小于根结点的值,且是一棵二叉树; • 若它的右子树不空,则右子树上所有结点的值均大于根结点的值,且是一棵二叉树;
二叉排序树中查找的过程 • 查找51,33 • 与根结点进行比较,如果和根结点的值相等,则找到了;如果比根结点的值大,则到右子树中查找;否则,到左子树中查找
二叉排序树插入 • 将31插入到右边的二叉排序树中 • 先找到要插入的位置(查找过程) • 将31插入到合适的位置
二叉排序树删除 • 将右边的二叉排序树中值为45删除 • 先找到要删除的结点(查找过程) • 删除该节点,并保持二叉树仍然是一个二叉排序树
删除节点的一般处理 • 用左子树中最大的结点代替该结点;或者用右子树中最小的结点代替该结点
具体的处理 • 如果待删除结点是叶子,如32,47 • 如果待删除结点只有左子树,如51,34 • 如果待删除节点只有右子树,如12 • 如果待删除结点左右子树均非空,如45,54
平均查找长度ASL • ASL=(1+2+2+3+3+3+4+4)/8=11/4=2.75<4 • 最好的情形: 完全二叉树 • 最差的情形: 单支树 ASL<=log2 n ASL=(n+1)/2
二叉排序树进行排序 • 特征:中序遍历为有序 • 用给定数据构造二叉排序树 • 中序遍历二叉排序树
平衡二叉树 • 定义 或者是一个棵空树,或者具有下列性质:它的左右子树都是平衡二叉树,且左右子树的高度相差(的绝对值)不超过1 • 结点的平衡因子:左子树高度减去右子树的高度 • 平衡二叉树上的结点平衡因子只能是-1,0,1
Hash(哈希)表 • Hash表的定义 由关键字直接确定存储位置 • Hash函数 根据关键字计算存储位置的函数
Hash函数的构造 • 直接定址 取关键字或者关键字的线性函数值为hash地址 例如: H(key)= key 或者 H(key)=a*key+b • 数字分析 关键字都是事先可知的,则可取关键字的若干位作为hash地址 例如: 学号10062364 ..10062396
Hash函数的构造 • 平方取中 取关键字平方后的中间几位为hash地址 例如: key key^2 H(key) 1100 12100 210 1160 137040 370 2161 4734741 734 2162 4741304 741
Hash函数的构造 • 折叠 将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几位的叠加和(舍去进位)作为hash地址 例如:0-442-20586-4 5864 5864 4220 0224 + 04 + 04 ———— ---------- 10088 6092
Hash函数的构造 • 除留余数 取关键字被某个不大于hash表长的m的数p除后所得余数为hash地址 H(key)= key mod p; p<=m 通常应选取p为质数或者不包含小于20的质因数的合数
Hash函数的构造 • 随机数 选择一个随机函数,取关键字的随机函数值为它的hash地址 H(key)= random (key) • 其他
Hash函数主要考虑因素 • 计算函数所需时间 • 关键字长度 • Hash表长度 • 关键字分布情况 • 记录的查找频率 • Hash函数导致地址冲突
处理冲突的方法 • 开放定址法 Hi=( H(key) + di ) mod m H(key) 是hash函数,m为表长, di 为增量序列 • di =1,2,3,..,m-1 线性探测再散列 • di =1,-1,22,-22, 32,..,-k2 (k<=m/2)二次探测再散列 • di =伪随机序列,伪随机探测再散列
处理冲突的方法 • 再Hash Hi=RHi ( key ) RHi 均是不同的hash函数,在同义词产生地址冲突的时候计算另一个hash函数地址,直到冲突不再产生
处理冲突的方法 • 双Hash函数 提供两个hash函数,第一个确定地址,第二个函数在冲突的时候提供探测的步长 例如:表长11 H1(key)= key mod 11 H2(key)=7-(key mod 7) 若key=58 则探测序列为:3,8,2
处理冲突的方法 • 链地址 将所有关键字为同义词的记录存储在同一线性表中 • 公共溢出区 一旦发生冲突,就将该数据放入溢出表
考虑下面的问题 • 现在用双函数法来计算hash地址。将数据放入hash表中时, • 如何表示地址冲突? • 需要将表中的一个数据删除时,应该怎么做?这对上面表示冲突的方法有影响吗?
平均查找长度 • 例 19 14 23 01 68 20 84 27 55 11 10 79 • 表长16 • Hash函数 H(key)= key mod 13 • 冲突解决方法:线性探测再散列 • 画出Hash表,并求出ASL
堆排序 • 锦标赛排序 • 什么是一个堆?(大、小顶堆) 大顶堆例:96,83,27,38,11,09 小顶堆例:12,36,24,85,47,30,53,91
如何构造一个堆(以大顶堆为例) • 例:49 38 65 97 76 13 27 51 • 从上往下 从只有一个元素的大顶堆开始,逐步增加数据仍保持是一个大顶堆 • 从下往上 把孩子已经是大顶堆的结点调整成一个大顶堆
堆排序 例 96,83,27,38,11,09,23,37,13 • 第一步 先构造一个堆 • 第二步 把构造好的堆按照顺序输出