第9章 查找

1,416 views

Published on

  • Be the first to comment

  • Be the first to like this

第9章 查找

  1. 1. 第 9 章 查 找 § 9.1 静态查找表 一、概念 1. 查找表 : 由同一种类型的数据元素 ( 或记录 ) 构成的集合,由于“集合”中的数据元素之间存在着松散的关系,因此查找表是一种应用灵便的数据结构 2. 静态查找表 : 仅作查询和检索操作的查找表 3. 动态查找表 : 在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已存在的某个数据元素 4. 关键字 : 是数据元素 ( 或记录 ) 中某个数据项的值,用它可以标识一个数据元素 ( 或记录 ) 5. 查找
  2. 2. 如何进行查找? 查找的方法取决于查找表的结构。 由于查找表中的数据元素之间不存在明显的组织规律,因此不便于查找。 为了提高查找的效率, 需要在查找表中的元素之间人为地附加某种确定的关系,换句话说, 用另外一种结构来表示查找表。
  3. 3. <ul><ul><li>查找方法评价 </li></ul></ul><ul><ul><ul><li>查找速度 </li></ul></ul></ul><ul><ul><ul><li>占用存储空间多少 </li></ul></ul></ul><ul><ul><ul><li>算法本身复杂程度 </li></ul></ul></ul><ul><ul><ul><li>平均查找长度 ASL(Average Search Length) :为确定记录在表中的位置,需和给定值进行比较的关键字的个数的期望值叫查找算法的平均查找长度 </li></ul></ul></ul>含有 n 个记录的表, 其中 :p i 为查找表中第 i 个元素的概率, c i 为找到表中第 i 个元素所需要比较的次数 ASL=
  4. 4. <ul><li>二、顺序表的查找 </li></ul>1 、静态查找表的顺序存储结构 typedef struct { ElemType *elem; int length; }SSTable; 2 、顺序查找 : 从表中最后一个记录开始,逐个进行记录的关键字和给定值的比较,若某个记录的关键字与给定值比较相等,则查找成功,反之,查找不成功
  5. 5. 0 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92 找 64 64 监视哨 比较次数 =5 比较次数: 查找第 n 个元素: 1 查找第 n-1 个元素: 2 ……… . 查找第 1 个元素: n 查找第 i 个元素: n+1-i 查找失败: n+1 查找过程:从表的一端开始逐个进行记录的关键字和给定值的比较 i i i i i
  6. 6. int Search_Seq(SSTable ST,keyType key) { ST.elem[0]=key; for(i=ST.length;!EQ(ST.elem[i].key,key);--i); return i; }
  7. 7. 顺序检索的缺点是查找时间长。假设顺序表中每个记录的查找概率相同,即 P i =1/n ( i=0 , 1 ,…, n-1 ),查找表中第 i 个记录所需的进行的比较次数 C i =n-i+1 。因此,顺序查找算法查找成功时的平均查找长度为: 算法分析: 查找失败时,算法的平均查找长度为: ASL=n+1 查找不成功情形不可忽略时: 平均查找长度=查找成功的 ASL +查找失败的 ASL ASL=(ASL 成功 +ASL 失败 )/2=3(n+1)/4 ASL=
  8. 8. 三、有序表的查找 顺序表的查找算法简单,但平均查找长度较大,不适用于表长较大的查找表。 若以 有序表 表示静态查找表,则查找过程可以基于“折半”进行 折半查找 ( 二分法 ) 查找过程:每次将待查记录所在区间缩小一半 适用条件:采用顺序存储结构的有序表
  9. 9. 1. 设表 l 长为 n , low 、 high 和 mid 分别指向待查元素所在区间的上界、下界和中点 ,k 为给定值 <ul><li>折半查找算法实现 </li></ul>2. 初始时,令 low=1 , high=n , mid=  (low+high)/2  让 k 与 mid 指向的记录比较 l[mid]. Key = k ,查找成功; l[mid]. Key > k ,把查找区间缩小到表的 前半部分 ,再继续进行对分查找,即 high=mid-1 l[mid]. Key < k ,把查找区间缩小到表的 后半部分 ,再继续进行对分查找,即 low=mid+1 3. 重复上述操作,直至 low>high 时,查找失败。
  10. 10. 有一组有序的线性表如下: ( 10 , 14 , 20 , 32 , 45 , 50 , 68 , 90 , 100 , 120 ) 例 下面分析在其中二分法查找关键字 20 的过程。 第 1 次比较, 20<45 ,调整到左半区 :high=mid-1 第 2 次比较, 14<20 ,调整到右半区 :low=mid+1 第 3 次比较, 20=20 ,查找成功,返回位置 3 low=1 1 2 3 4 5 6 7 8 9 10 120 100 90 68 50 45 32 20 14 10 high=10 mid=5 high=4 mid=2 low=3 mid=3
  11. 11. 例 key =70 的查找过程 low high mid 找 70 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92 low high mid 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92 low high mid 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92 low high mid 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92
  12. 12. 1 2 3 4 5 6 7 8 9 10 11 5 13 19 21 37 56 64 75 80 88 92 low high 当下界 low 大于上界 high 时,则说明表中没有关键字等于 Key 的元素,查找不成功。
  13. 13. 先看一个有 11 个元素的表的例子: n=11 折半查找的性能分析 <ul><ul><ul><li>判定树:描述查找过程的二叉树 </li></ul></ul></ul><ul><ul><ul><li>有 n 个结点的判定树的深度为  log 2 n  +1 </li></ul></ul></ul><ul><ul><ul><li>折半查找法在查找过程中进行的比较次数最多不超过  log 2 n  +1 </li></ul></ul></ul>6 3 9 1 4 2 5 7 8 10 11 i 1 2 3 4 5 6 7 8 9 10 11 Ci 1 2 2 3 3 3 3 4 4 4 4
  14. 14. 假设 有序表的长度 n=2 h -1 (反之 h=log 2 (n+1) ) , 则描述折半查找的判定树是深度为 h 的满二叉树。树中层次为 1 的结点有 1 个,层次为 2 的结点有 2 个,层次为 h 的结点有 2 h-1 个。假设表中每个记录的查找概率相等 则查找成功时折半查找的平均查找长度 在 n>50 时,可得近似结果 折半查找的效率比顺序查找高。 折半查找只能适用于有序表,并且以顺序存储结构存储
  15. 15. § 9.2 动态查找表 动态查找表的特点 : 表结构本身是在查找过程中动态生成。若表中存在其关键字等于给定值 key 的记录 , 表明查找成功;否则插入关键字等于 key 的记录。 <ul><li>一、二叉排序树的定义 </li></ul><ul><li>二叉排序树或者是一棵空树 ; 或者是具有如下特性的二叉树: </li></ul><ul><li>若它的左子树不空,则左子树上所有结点的值均小于根结点的值 </li></ul><ul><li>若它的右子树不空,则右子树上所有结点的值均大于根结点的值 </li></ul><ul><li>它的左、右子树也都分别是二叉排序树 </li></ul>
  16. 16. 按中序遍历该树所得到的中序序列是一个递增有序序列 50 30 80 20 90 10 85 40 35 25 23 88 66 45 12 53 3 99 61 37 24 90 70
  17. 17. <ul><li>若二叉排序树为空,则查找不成功; </li></ul><ul><li>否则 </li></ul><ul><li>1 )若给定值等于根结点的关键字,则查找成功; </li></ul><ul><li>2 )若给定值小于根结点的关键字,则继续在左子树上进行查找; </li></ul><ul><li>3 )若给定值大于根结点的关键字,则继续在右子树上进行查找。 </li></ul>二、二叉排序树的查找算法
  18. 18. 在二叉排序树中查找关键字值等于 50, 35 , 90 , 95 50 30 80 20 90 85 40 35 88 32 50 50 50 30 40 35 50 50 80 90
  19. 19. 三、二叉排序树的生成和删除 1 、二叉排序树的生成 <ul><li>若 b 是空树 , 则将 s 所指的结点作为根结点插入 ; 否则 </li></ul><ul><li>若 s->data 等于 b 的根结点的 data, 则返回 ; 否则 </li></ul><ul><li>若 s->data 小于 b 的根结点的 data, 则把 s 所指结点插入到左子树中 ; 否则 </li></ul><ul><li>把 s 所指结点插入到右子树中 </li></ul>
  20. 20. 例 :{40,28,6,72,98,3,54,1,80,91,38} 40 一个无序序列可以通过构造一棵二叉排序树二而变成一个有序序列 54 72 6 98 80 38 91 3 1 28
  21. 21. <ul><li>和插入相反,删除在查找成功之后进行,并且要求在删除二叉排序树上某个结点之后,仍然保持二叉排序树的特性 </li></ul><ul><li>可分三种情况讨论: </li></ul><ul><li>被删除的结点是叶子 </li></ul><ul><li>被删除的结点只有左子树或者只有右子树 </li></ul><ul><li>被删除的结点既有左子树,也有右子树 </li></ul>2 、二叉排序树的删除
  22. 22. 被删除的结点是叶子结点 , 如 key=88 方法:直接删除该结点,将其双亲结点中相应指针域的值改为空 50 30 80 20 90 85 40 35 88 32 50 30 80 20 90 85 40 35 32
  23. 23. 方法:其双亲结点的相应指针域的值改为 “指向被删除结点的左子树或右子树” 被删除的结点只有左子树或只有右子树 , 如 key=80 50 30 80 20 90 85 40 35 88 32 50 30 20 90 85 40 35 88 32
  24. 24. 方法 : 可在它右子树中寻找关键字最小的结点放在被删结点的位置上,将其原来的右子树作为它原来的双亲结点的左子树 ; 或在它左子树中寻找关键字最大的结点放在被删结点的位置上,将其原来的左子树作为它原来双亲结点的右子树 被删除的结点既有左子树又有右子树 , 如 key=50 50 30 80 20 90 85 40 35 88 32 85 30 80 20 90 40 35 88 32 40 30 80 20 90 85 35 88 32
  25. 25. 四、平衡二叉排序树 平衡二叉树又称为 AVL 树,它或是一棵空树,或是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树高度之差的绝对值不超过 1 。 此处规定二叉树的高度是二叉树的树叶的最大层数,也就是从根结点到树叶的最大路径长度。 相应地,二叉树中某个结点的左子树高度与右子树高度之差称为该结点的平衡因子(或平衡度)。由此可知,平衡二叉树也就是树中任意结点的平衡因子的绝对值小于等于 1 的二叉树。
  26. 26. 如果一棵二叉排序树满足平衡二叉树的定义便是一棵平衡的二叉排序树,平衡的二叉排序树又称为平衡查找树。 研究平衡二叉树的目的在于如何动态地使一棵二叉排序树保持平衡,从而使它具有较高的检索效率。
  27. 27. 动态保持二叉排序树平衡的方法: ( 1 )插入 ( 2 )调整平衡度 ( 1 )插入:不考虑结点的平衡度,使用在二叉排序树中插入新结点的方法,把结点 k 插入树中,同时置新结点的平衡度为 0 。 ( 2 )调整平衡度:假设 k 0 , k 1 ,…, k m =k 是从根 k 0 到插入点 k 路径上的结点,由于插入了结点 k ,就需要对这条路径上的结点的平衡度进行调整,取失去平衡的最小子树进行调整
  28. 28. 下面具体讨论 AVL 树上因插入新结点而导致失去平衡时的调整方法。 为叙述方便,假设在 AVL 树上因插入新结点而失去平衡的最小子树的根结点为 A (即 A 为距离插入结点最近的,平衡因子不是 -1 、 0 和 1 的结点)。失去平衡后的调整操作可依据失去平衡的原因归纳为下列四种情况分别进行。
  29. 29. ( 1 ) LL 型平衡旋转:由于在 A 的左孩子的左子树上插入新结点,使 A 的平衡度由 1 增至 2 ,致使以 A 为根的子树失去平衡,如图 9.9 ( a )所示。此时应进行一次顺时针旋转,“提升” B (即 A 的左孩子)为新子树的根结点, A 下降为 B 的右孩子,同时将 B 原来的右子树 Br 调整为 A 的左子树。 图 9.9 (a) A 2 B 1 B L B r A r h h h LL 型 A 0 B 0 B L B r A r h h h
  30. 30. ( 2 ) RR 型平衡旋转:由于在 A 的右孩子的右子树上插入新结点,使 A 的平衡度由 -1 变为 -2 ,致使以 A 为根的子树失去平衡,如图 9.9 ( b )所示。此时应进行一次逆时针旋转,“提升” B (即 A 的右孩子)为新子树的根结点, A 下降为 B 的左孩子,同时将 B 原来的左子树 BL 调整为 A 的右子树。 图 9.9 (b) A -2 B -1 B r B L A L h h h RR 型 A 0 B 0 B r A L B L h h h
  31. 31. ( 3 ) LR 型平衡旋转:由于在 A 的左孩子的右子树上插入新结点,使 A 的平衡度由 1 变成 2 ,致使以 A 为根的子树失去平衡,如图 9.9 ( c )所示。此时应进行两次旋转操作(先逆时针,后顺时针),即“提升” C (即 A 的左孩子的右孩子)为新子树的根结点; A 下降为 C 的右孩子; B 变为 C 的左孩子; C 原来的左子树 CL 调整为 B 现在的右子树; C 原来的右子树 Cr 调整为 A 现在的左子树 图 9.9 (c) A 2 B -1 A r h B L h LR 型 C C L h-1 C r h-1 1 A -1 B 0 A r h B L h C L h-1 C r h-1 C 0
  32. 32. ( 4 ) RL 型平衡旋转:由于在 A 的右孩子的左子树上插入新结点,使 A 的平衡度由 -1 变成 -2 ,致使以 A 为根的子树失去平衡,如图 9.9 ( d )所示。此时应进行两旋转操作(先顺时针,后逆时针),即“提升” C (即 A 的右孩子的左孩子)为新子树的根结点; A 下降 C 的左孩子; B 变为 C 的右孩子; C 原来的左子树 CL 调整为 A 现在的右子树; C 原来的右子树 Cr 调整为 B 现在的左子树。 图 9.9 (d) B -1 A 0 B r h A L h C L h-1 C r h-1 C 0 A -2 B 1 B r h A L h RL 型 C L h-1 C r h-1 C 1
  33. 33. 综上所述,在平衡的二叉排序树 t 上插入一个新的数据元素 x 的算法可描述如下: (一)若 AVL 树 t 为空树,则插入一个数据元素为 x 的新结点作为 t 的根结点,树的深度增 1 ; (二)若 x 的关键字和 AVL 树 t 的根结点的关键字相等,则不进行插入; (三)若 x 的关键字小于 AVL 树 t 的根结点的关键字,则将 x 插入在该树的左子树上,并且当插入之后的左子树深度增加 1 时,分别就下列不同情况进行分情形处理: ( 1 )若 AVL 树的根结点的平衡因子为 -1 (右子树的深度大于左子树的深度),则将根结点的平衡因子调整为 0 ,并且树的深度不变;
  34. 34. ( 2 )若 AVL 树的根结点的平衡因子为 0 (左、右子树的深度相等),则将根结点的平衡因子调整为 1 ,树的深度同时增 1 ; ( 3 )若 AVL 树的根结点的平衡因子为 1 (左子树的深度大于右子树的深度),则当该树的左子树的根结点的平衡因子为 1 时需进行 LL 型平衡旋转;当该树的左子树的根结点的平衡因子为 -1 时需进行 LR 型平衡旋转。 (四)若 x 的关键字大于 AVL 树 t 的根结点的关键字,则将 x 插入在该树的右子树上,并且当插入之后的右子树深度增加 1 时,需要分别就不同情况进行处理。其处理操作和(三)中所述相对称
  35. 35. 结点序列( 120 , 80 , 30 , 90 , 45 , 60 )逐个插入一棵空的 AVL 树的过程如下: 120 0 120 1 80 0 120 2 80 1 30 0 120 0 80 0 30 0 120 1 80 -1 30 0 90 0 120 1 80 0 30 -1 90 0 45 0 120 1 80 0 30 -2 90 0 45 -1 60 0 120 1 80 0 30 0 90 0 45 0 60 0
  36. 36. 依次把结点值为 60 , 40 , 30 , 150 , 130 , 50 , 90 , 80 , 96 , 25 的记录插入到初始为空的平衡二叉排序树中,使得在每次插入后保持该树仍然是平衡查找树。请依次画出每次插入后所形成的平衡查找树。
  37. 37. § 9.3 哈希表 一、哈希表的相关定义 哈希函数 : 在记录的关键字与记录的存储地址之间建立的一种对应关系。哈希函数是一种映象,是从关键字空间到存储地址空间的一种映象。 可写成, addr(ai)=H(ki) 其中: ai 是表中的一个元素 addr(ai) 是 ai 的存储地址 ki 是 ai 的关键字
  38. 38. 例 : { 刘丽 , 刘宏英 , 吴进 , 吴小艳 , 李秋梅 , 陈伟 } 26 25 24 …… 3 2 1 z y x …… c b a 26 42 72 33 46 24 用所有首字母编号值相加求和 cw lqm wxy wj lhy ll 姓名中各字拼音首字母 陈伟 李秋梅 吴小艳 吴进 刘宏英 刘丽
  39. 39. 问题:如果两个同学分别叫刘丽、刘兰 ,该如何处理这两条记录? 这个问题是哈希表不可避免的,即 冲突现象 :对不同的关键字可能得到同一哈希地址 …… …… 吴小艳 76 …… …… …… … …… …… …… … …… …… 刘宏英 46 …… …… …… … …… …… 李秋梅 42 …… …… …… … …… …… 吴进 33 …… …… …… … …… …… 陈伟 26 …… …… …… … …… …… 刘丽 24 …… …… …… …
  40. 40. 哈希表 : 根据设定的哈希函数 H(key) 和所选中的处理冲突的方法,将一组关键字映象到一个有限的、地址连续的地址集 ( 区间 ) 上,并以关键字在地址集中的“象”作为相应记录在表中的存储位置,如此构造所得的查找表称之为“哈希表” <ul><ul><ul><li>可见: </li></ul></ul></ul><ul><ul><ul><li>哈希函数只是一种映象,所以哈希函数的设定很灵活,只要使任何关键字的哈希函数值都落在表长允许的范围之内即可。 </li></ul></ul></ul><ul><ul><ul><li>冲突: key1  key2 ,但 H(key1)=H(key2) 的现象 </li></ul></ul></ul>
  41. 41. <ul><ul><li>直接定址法 </li></ul></ul><ul><ul><li>数字分析法 </li></ul></ul><ul><ul><li>平方取中法 </li></ul></ul><ul><ul><li>折叠法 </li></ul></ul><ul><ul><li>除留余数法 </li></ul></ul><ul><ul><li>随机数法 </li></ul></ul>二、哈希函数的构造方法
  42. 42. 哈希函数为关键字的线性函数 H(key)=key 或者 H(key)=a  key + b (a 和 b 为常数 ) 此法仅适合于: 地址集合的大小 = = 关键字集合的大小 1 、直接定址法
  43. 43. 设定哈希函数为 : H(key) = key MOD p ( p≤m ) m 为表长 p 为不大于 m 的质数 或是 不含小于 20 的质因素的合数 2 、除留余数法 例:给定一组关键字为 : 12, 39, 18, 24, 33, 21 , 若取 p=9, 则他们对应的哈希函数值将为 : 3, 3, 0, 6, 6, 3 可见,若 p 中含质因子 3, 则所有含质因子 3 的关键字均映射到“ 3 的倍数”的地址上,从而增加了“冲突”的可能 为什么要对 p 加限制?
  44. 44. 设定哈希函数为 : H(key) = Random(key) 其中, Random 为伪随机函数 此法用于构造关键字长度不等的哈希函数。 3 、随机数法 <ul><li>选取哈希函数考虑的因素: </li></ul><ul><ul><ul><ul><li>计算哈希函数所需时间 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>关键字长度 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>哈希表长度(哈希地址范围) </li></ul></ul></ul></ul><ul><ul><ul><ul><li>关键字分布情况 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>记录的查找频率 </li></ul></ul></ul></ul>
  45. 45. —— 为产生冲突的地址寻找下一个哈希地址 三、处理冲突的方法 开放定址法 再哈希法 链地址法
  46. 46. <ul><ul><ul><li>为产生冲突的地址 H(key) 求得一个地址序列: </li></ul></ul></ul><ul><ul><ul><li>H 0 , H 1 , H 2 , …, H s ( 1≤s≤m-1 ) </li></ul></ul></ul><ul><ul><ul><li>H i = ( H(key) + d i ) MOD m </li></ul></ul></ul><ul><ul><ul><li>(i=1, 2, …, s H(key) 为哈希函数 m 为哈希表长 ) </li></ul></ul></ul><ul><ul><ul><li>d i 为增量序列 , 有下列三种取法 : </li></ul></ul></ul>1 、开放定址法 1) 线性探测再散列 d i = 1,2,3,……,m-1 2) 二次探测再散列 d i = 1 2 , -1 2 , 2 2 , -2 2 , …… 3) 随机探测再散列 d i = 伪随机数列
  47. 47. 例 : 表长为 11 的哈希表中已填有关键字为 17 , 60 , 29 的记录, H(key)=key MOD 11, 现有第 4 个记录,其关键字为 38 ,按三种处理冲突的方法,将它填入表中 (1) H( 38 )=38 MOD 11=5 冲突 H1=(5+1) MOD 11=6 冲突 H2=(5+2) MOD 11=7 冲突 H3=(5+3) MOD 11=8 不冲突 (2) H( 38 )=38 MOD 11=5 冲突 H1=(5+1²) MOD 11=6 冲突 H2=(5-1²) MOD 11=4 不冲突 (3) H( 38 )=38 MOD 11=5 冲突 设伪随机数序列为 9 ,则: H1=(5+9) MOD 11=3 不冲突 60 17 29 38 38 38 0 1 2 3 4 5 6 7 8 9 10
  48. 48. 例如 : 给定关键字集合构造哈希表 { 19, 01, 23, 14, 55, 68, 11, 82, 36 } 设定哈希函数 H(key) = key MOD 11 ( 表长 =11 ) 19 01 23 14 55 68 19 01 23 14 68 若采用线性探测再散列处理冲突 若采用二次探测再散列处理冲突 11 82 36 55 11 82 36 1 1 2 1 1 3 6 2 5 1 1 2 1 1 4 4 1 4 0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 10
  49. 49. <ul><ul><ul><li>将所有哈希地址相同的记录都链接在同一链表中 </li></ul></ul></ul><ul><li>例 : 给定关键字 </li></ul><ul><li>{ 19, 01, 23, 14, 55, 68, 11, 82,36 } </li></ul><ul><li>哈希函数为 H(key)=key MOD 7 </li></ul><ul><ul><ul><li>2 、链地址法 </li></ul></ul></ul>0 1 2 3 4 5 6  11  19 82 68  55  14 36  01  23 
  50. 50. <ul><ul><ul><li>再哈希法 </li></ul></ul></ul><ul><ul><ul><ul><li>方法:构造若干个哈希函数,当发生冲突时,计算下一个哈希地址, </li></ul></ul></ul></ul><ul><ul><ul><ul><li>直到冲突不再发生。 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>即: Hi=Rhi(key) i=1,2,……k </li></ul></ul></ul></ul><ul><ul><ul><ul><li>其中: Rhi—— 不同的哈希函数 </li></ul></ul></ul></ul>
  51. 51. <ul><ul><li>哈希查找过程 </li></ul></ul>哈希表的查找 对于给定值 K, 计算哈希地址 i = H(K) 若 r[i] = NULL 则查找不成功 , 若 r[i].key = K 则查找成功 , 否则 “求下一地址 Hi” , 直至 r[Hi] = NULL ( 查找不成功 ) 或 r[Hi].key = K ( 查找成功 ) 为止。 给定 k 值 计算 H(k) 此地址为空 关键字 ==k 查找失败 查找成功 按处理冲突 方法计算 Hi Y N Y N
  52. 52. 例 : 已知关键字 (19,14,23,1,68,20,84,27,55,11,10,79) 哈希函数为 H(key)=key MOD 13, 哈希表长为 m=16 , 用线性探测再散列处理冲突得哈希表 14 1 68 27 55 19 20 84 79 23 11 10 给定值 K=38 的查找过程为 : H(38)=12 不空且不等于 38, 冲突 H1=(12+1)MOD16=13 空记录 表中不存在关键字等于 38 的记录 , 查找不成功。 给定值 K=84 的查找过程为 : H(84)=6 不空且不等于 84, 冲突 H1=(6+1)MOD16=7 不空且不等于 84, 冲突 H2=(6+2)MOD16=8 不空且等于 84, 查找成功 , 返回记录在表中的序号。 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
  53. 53. 哈希表查找的分析 <ul><li>从查找过程得知,哈希表查找的平均查找长度实际上并不等于零。 </li></ul><ul><li>决定哈希表查找的 ASL 的因素: </li></ul><ul><li>1) 选用的哈希函数 ; </li></ul><ul><li>2) 选用的处理冲突的方法 ; </li></ul><ul><li>哈希表饱和的程度,装载因子 α=n/m 值的大小 </li></ul><ul><li>( n— 表中填入的记录数, m— 表的长度) </li></ul>
  54. 54. 例如 : 给定关键字集合构造哈希表 { 19, 01, 23, 14, 55, 68, 11, 82, 36 } 设定哈希函数 H(key) = key MOD 11 ( 表长 =11 ) 19 01 23 14 55 68 若采用线性探测再散列处理冲突 11 82 36 1 1 2 1 1 3 6 2 5 ASL=(1*4+2*2+3+5+6)/9=22/9 ASL=(1*5+2*1+4*3)/9=19/9 若采用二次探测再散列处理冲突 0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 10 19 01 23 14 68 55 11 82 36 1 1 2 1 1 4 4 1 4
  55. 55. <ul><ul><ul><li>例 : 给定关键字 </li></ul></ul></ul><ul><li>{ 19, 01, 23, 14, 55, 68, 11, 82,36 } </li></ul><ul><li>哈希函数为 H(key)=key MOD 7 </li></ul>ASL=(1*6+2*2+3)/9=13/9 0 1 2 3 4 5 6  11  19 82 68  55  14 36  01  23 
  56. 56. 线性探测再散列 链地址法 随机探测再散列 可以证明:查找成功时有下列结果:
  57. 57. 练习: 已知一组关键字 (19,14,23,1,68,20,84,27,55,11,10,79) 哈希函数为: H(key)=key MOD 13, 用链地址法处理冲突,并计算查找成功时的平均查找长度 ASL=(1*6+2*4+3+4)/12=21/12=7/4 0 1 2 3 4 5 6 7 8 9 10 11 12 14 ^ 1 27 79 68 55 19 84 20 23 10 11 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^

×