版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第三章第三章 查找与排序技术查找与排序技术 第三章第三章 查找与排序技术查找与排序技术 3.1 基本查找技术基本查找技术 查找:查找:在一个给定的数据结构中查找某个指定在一个给定的数据结构中查找某个指定 的元素。的元素。 通常,根据不同的通常,根据不同的数据结构数据结构,应该采用不同的,应该采用不同的 查找方法:查找方法: 顺序查找;顺序查找; 有序表的对分查找;有序表的对分查找; 分块查找。分块查找。 3.1.1 顺序查找顺序查找 顺序查找(顺序搜索):顺序查找(顺序搜索):在线性表中查找指定在线性表中查找指定 的元素。的元素。 顺序查找的基本方法:顺序查找的基本方法:从线性表的第一个元素从
2、线性表的第一个元素 开始,依次将线性表中的元素与被查元素进行开始,依次将线性表中的元素与被查元素进行 比较,若相等则表示找到(比较,若相等则表示找到(查找成功查找成功);若线);若线 性表中的所有元素都与被查元素进行了比较但性表中的所有元素都与被查元素进行了比较但 都不相等,则表示线性表中没有要找到的元素都不相等,则表示线性表中没有要找到的元素 (查找失败查找失败)。)。 回顾回顾:举例说明举例说明 举例举例:设设L是包是包 含含n个元素的一个元素的一 维数组。对于指维数组。对于指 定的输入定的输入x,如如 果果x在数组中,在数组中, 则顺序找到它第则顺序找到它第 一次出现处的下一次出现处的下
3、 标;标; 如果如果x不在数不在数 组中,则以组中,则以 下标下标0作为查作为查 找结果。找结果。 算法算法:顺序搜索法(:顺序搜索法(Sequential Search)。)。 输入:一维数组输入:一维数组L(1:n),被查项被查项x。 输出:第一次使输出:第一次使L(j)=x的的j,若若x不不 在数组在数组L中,则输出中,则输出j=0。 j1 WHILE (jn)and(L(j)x) DO jj+1 IF jn THEN j0 OUTPUT j RETURN 被访问的数组元素下标被访问的数组元素下标 如果没有被访问如果没有被访问 到数组尾部,且到数组尾部,且 暂时没有发现元暂时没有发现元
4、素值等于素值等于x。 回顾回顾:平均性态分析平均性态分析 设被查项设被查项x在数组在数组L中的概率为中的概率为q。当输入的当输入的x为为 L(i)时,算法所做的比较次数为:时,算法所做的比较次数为: 1, 1 , )( nin nii iLT 1,1 1 , )( niq ni n q iLp 再假设输入的再假设输入的x出现在数组中的每个位置上的出现在数组中的每个位置上的 可能性是一样的,即可能性是一样的,即 其中其中x=L(n+1)表示表示x不在数组不在数组L中的情况。中的情况。 顺序查找的效率顺序查找的效率 如果线性表中的如果线性表中的第一个元素第一个元素就是被查找元素,就是被查找元素,
5、只需要做一次比较就只需要做一次比较就查找成功查找成功; 如果被查的元素是线性表中的如果被查的元素是线性表中的最后一个元素最后一个元素, 或者被查元素根本不在线性表中,则需要与线或者被查元素根本不在线性表中,则需要与线 性表中的所有元素进行比较(性表中的所有元素进行比较(最坏情况最坏情况);); 平均情况:平均情况:利用顺序查找法在线性表中查找一利用顺序查找法在线性表中查找一 个元素,大约要与个元素,大约要与线性表中一半的元素线性表中一半的元素进行比进行比 较。较。 结论结论 对于大的线性表来说,对于大的线性表来说,顺序查找的效率是很顺序查找的效率是很 低低的。但在下列两种情况下也只能采用顺序的
6、。但在下列两种情况下也只能采用顺序 查找:查找: 如果线性表为如果线性表为无序表无序表(表中元素的排列是无(表中元素的排列是无 序的),则不管是顺序存储结构还是链式存序的),则不管是顺序存储结构还是链式存 储结构,都只能用顺序查找法;储结构,都只能用顺序查找法; 1. 即使是即使是有序线性表有序线性表,如果采用链式存储结构如果采用链式存储结构, 也只能用顺序查找。也只能用顺序查找。 3.1.2 有序表的对分查找有序表的对分查找 有序表有序表:线性表中的元素按值非递减或者非递增线性表中的元素按值非递减或者非递增 排列。排列。 对分查找的过程:对分查找的过程:将被查找关键字与将被查找关键字与线性表
7、中间线性表中间 的项目的项目进行比较,有三种可能:进行比较,有三种可能: 若被查关键字与表中间的项目相等,则查到,过若被查关键字与表中间的项目相等,则查到,过 程结束;程结束; 若被查关键字大于表中间的项目,则取表的后半若被查关键字大于表中间的项目,则取表的后半 部分作为新表再去查找;部分作为新表再去查找; 1. 若被查关键字小于表中间的项目,则取表的前半若被查关键字小于表中间的项目,则取表的前半 部分作为新表再去查找。部分作为新表再去查找。 升序升序降序降序 查找成功!查找成功! 在后半部分查找!在后半部分查找! 在前半部分查找!在前半部分查找! 减半递推!减半递推! 举例:在下列数据中查找
8、元素举例:在下列数据中查找元素2626 010205091113161921262731 low high middle lowhighmiddle lowmiddle high 第一次 第二次 第三次 对分法查找优点: 平均检索长度小,为log2n high 第四次 #include /using namespace std; template class SL_List private: int mm; int nn; T *v; public: /只定义对象名只定义对象名 SL_List() mm=0; nn=0; return; int search_SL_List(T); /顺序有序
9、表查找顺序有序表查找 顺序有序表的长度顺序有序表的长度 顺序有序表的对分查找顺序有序表的对分查找 /顺序有序表查找顺序有序表查找 template int SL_List:search_SL_List( T x ) int i, j, k; i = 1; j = nn; while (ix ) j = k - 1; /取前半部分取前半部分 else i = k + 1; /取后半部分取后半部分 return (-1); /找不到返回找不到返回 查找范围从数组中第查找范围从数组中第i个元素开个元素开 始,到第始,到第j个元素结束。个元素结束。 找到表中间元素找到表中间元素vk-1 下一次查找从第
10、下一次查找从第i 个元素开始,到第个元素开始,到第 k-1个元素结束。个元素结束。 下一次查找从第下一次查找从第 k+1个元素开始,个元素开始, 到第到第j个元素结束。个元素结束。 时间效率分析时间效率分析 对分查找是根据每次试探的结果将线性表的规对分查找是根据每次试探的结果将线性表的规 模减半,并有规则地括出可能包含被查项目的模减半,并有规则地括出可能包含被查项目的 部分。部分。 最坏情况:最坏情况:对查找需要的比较次数为对查找需要的比较次数为 n为线性表的长度。为线性表的长度。 局限性:局限性:只适用于只适用于有序表有序表,且只限于,且只限于顺序存储顺序存储 结构结构。 1log2 n 3
11、.1.3 分块查找分块查找 分块查找又称分块查找又称索引查找索引查找,是顺序查找的一种改,是顺序查找的一种改 进方法,用于在进方法,用于在“分块有序分块有序”表表中进行查找。中进行查找。 “分块有序分块有序”表表:将长度为将长度为n线性表线性表L分成分成m个个 子表(各子表的长度可以不等,也可以相等),子表(各子表的长度可以不等,也可以相等), 且且后一个子表中的每一项均大于前一个子表中后一个子表中的每一项均大于前一个子表中 的所有项的所有项。 分块有序表分块有序表 分块有序表分块有序表的结构可以分为两部分:的结构可以分为两部分: (1)(1)线性表本身采用线性表本身采用顺序存储结构顺序存储结
12、构也可以采用也可以采用链式链式 存储结构存储结构。 (2)(2)再建立一个再建立一个索引表索引表。在索引表中,对线性表的。在索引表中,对线性表的 每个子表建立一个每个子表建立一个索引结点索引结点,每个结点包括两,每个结点包括两 个域:一是个域:一是数据域数据域,用于存放对应子表中的,用于存放对应子表中的最最 大元素值大元素值;二是;二是指针域指针域,用于指示对应子表的,用于指示对应子表的 第一个元素在整个线性表中的第一个元素在整个线性表中的序号序号或者或者地址地址。 图图3.1 分块有序表例(第分块有序表例(第161页)页) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 1
13、5 16 17 18 22 12 13 08 09 20 33 42 44 38 24 46 60 58 74 47 86 53 分析分析 根据分块有序表的结构,其查找过程可以分以根据分块有序表的结构,其查找过程可以分以 下两步进行:下两步进行: (1)(1)首先查找索引表,以便确定被查元素所在的首先查找索引表,以便确定被查元素所在的 子表。由于索引表数据域中的数据是有序的且子表。由于索引表数据域中的数据是有序的且 顺序存储,因此可以采用顺序存储,因此可以采用对分查找对分查找。 (2)(2)然后在相应的子表中用然后在相应的子表中用顺序查找法顺序查找法进行具体进行具体 的查找。的查找。 结论:分
14、块查找的效率介于对分查找和顺序查结论:分块查找的效率介于对分查找和顺序查 找之间。找之间。 顺序查找、折半查找,这些查找技术都是通过一顺序查找、折半查找,这些查找技术都是通过一 系列的给定值与关键码的比较,查找效率依赖于系列的给定值与关键码的比较,查找效率依赖于 查找过程中进行的给定值与关键码的比较次数。查找过程中进行的给定值与关键码的比较次数。 1.1.查找操作要完成什么任务?查找操作要完成什么任务? 待查值待查值k 确定确定k在存储结构中的位置在存储结构中的位置 2.2.我们学过哪些查找技术?这些查找技术的共性?我们学过哪些查找技术?这些查找技术的共性? 在存储位置和关键码之间建立一个确定
15、的对应关系在存储位置和关键码之间建立一个确定的对应关系 3.3.能否不用比较,通过关键码直接确定存储位置?能否不用比较,通过关键码直接确定存储位置? 例例1 1 假设有一个含有假设有一个含有8080个记录的查个记录的查 找表,记录的关键字均为两位找表,记录的关键字均为两位 的十进制数,则设有存储记录的十进制数,则设有存储记录 的数组为:的数组为: ElemType hashtable100;ElemType hashtable100; 并令关键字为并令关键字为keykey的记录存的记录存 在数组的第在数组的第i i个分量个分量 hashtableihashtablei中。中。 9999 585
16、8 5757 5656 033 022 011 0 i=f1(key)=key 例例2 2 假设一组记录的关键字,则设假设一组记录的关键字,则设 有存储记录的数组为:有存储记录的数组为: ElemType hashtable26;ElemType hashtable26; 并令关键字为并令关键字为keykey的记录存的记录存 在数组的第在数组的第i i个分量个分量 hashtableihashtablei中。中。 ZHAO25 YI24 XIAO23 WU22 GAO6 CHEN2 BAI1 0 i = f2(key) = 关键字的第一个字母的关键字的第一个字母的ASCII码码 A的的ASCI
17、I码码 在存储位置和关键码之间建立一个确定的对应关系在存储位置和关键码之间建立一个确定的对应关系 3.3.能否不用比较,通过关键码直接确定存储位置?能否不用比较,通过关键码直接确定存储位置? 在存储位置和关键码之间建立一个确定的对应关系在存储位置和关键码之间建立一个确定的对应关系 3.3.能否不用比较,通过关键码直接确定存储位置?能否不用比较,通过关键码直接确定存储位置? 关关 键键 码码 集集 合合 ki ri H( (ki) ) H 一一. .有关概念有关概念 1 1、哈希函数、哈希函数 用来定义记录的关键字与记录存储位用来定义记录的关键字与记录存储位 置的对应关系的函数。其自变量是记置的
18、对应关系的函数。其自变量是记 录的关键字,函数值是记录存储位置录的关键字,函数值是记录存储位置 3.2 3.2 哈希表哈希表 关关 键键 码码 集集 合合 ki ri H( (ki) ) H 哈希函数哈希函数 i=f1(key)=key 一一. .有关概念有关概念 3.2 哈希表哈希表 2 2、哈希地址、哈希地址 由哈希函数求出的记录存储位置称由哈希函数求出的记录存储位置称 为哈希地址为哈希地址 关关 键键 码码 集集 合合 ki ri H( (ki) ) H 哈希函数哈希函数 哈希地址哈希地址 一一. .有关概念有关概念 3.2 哈希表哈希表 3 3、哈希表、哈希表也叫散列表,是将记录按哈希
19、函数也叫散列表,是将记录按哈希函数 确定的位置存放而构成的表确定的位置存放而构成的表 关关 键键 码码 集集 合合 ki ri H( (ki) ) H 哈希函数哈希函数 哈希地址哈希地址 散列表散列表 数组数组 散列技术仅仅是一种查找技术吗?散列技术仅仅是一种查找技术吗? 散列既是一种查找技术,也是一种存储技术。散列既是一种查找技术,也是一种存储技术。 散列只是通过记录的关键码定位该记录,没散列只是通过记录的关键码定位该记录,没 有完整地表达记录之间的逻辑关系,所以,散列有完整地表达记录之间的逻辑关系,所以,散列 主要是主要是面向查找面向查找的存储结构。的存储结构。 散列是一种散列是一种完整的
20、存储结构完整的存储结构吗?吗? 3.2 哈希表哈希表 一一. .有关概念有关概念 3.2.1 哈希表的基本概念哈希表的基本概念 1. 直接查找技术直接查找技术 设表的长度为设表的长度为n。如果存在一个如果存在一个函数函数ii(k),对对 于表中的任意一个于表中的任意一个元素元素的的关键字关键字k,满足以下满足以下 条件:条件: (1)函数值函数值i的范围为:的范围为:1in; (2)对于任意的元素关键字对于任意的元素关键字k1k2,恒存在恒存在 i(k1)i(k2)。 则称此表为则称此表为直接查找表直接查找表。 其中函数其中函数ii(k)称为关键字称为关键字k的的映象函数映象函数。 直接查找技
21、术直接查找技术 直接查找表中各元素的关键字直接查找表中各元素的关键字k与表项序号与表项序号i之之 间存在着间存在着一一对应的关系一一对应的关系; 对直接查找表的查找,只需要根据对直接查找表的查找,只需要根据映像函数映像函数 i=i(k)计算出待查关键字项目在表中的计算出待查关键字项目在表中的序号序号i即即 可。可。 直接查找技术要求映像函数能使得表中任意两个直接查找技术要求映像函数能使得表中任意两个 不同的关键字其映像函数值也不同(不同的关键字其映像函数值也不同(不允许元素不允许元素 冲突的存在冲突的存在);但在实际应用中,这一条件很难);但在实际应用中,这一条件很难 满足。满足。 对于两个不
22、同的关键字对于两个不同的关键字k1 k2有有i(k1)=i(k2),发生发生 了了元素冲突元素冲突,即,即两个不同元素需要存在在同一个两个不同元素需要存在在同一个 存储单元中存储单元中。 举例举例 例例3.2 将关键字序列将关键字序列(09,31,26,19,01,13, 02,11,27,16,05,21)依次填入长度为依次填入长度为n12 的表中。映象函数为的表中。映象函数为iINT(k/3)1。 关键字关键字01和和02发生冲突:发生冲突: 因为两个数值都想要存因为两个数值都想要存 放在表的第放在表的第1项中。项中。 关键字关键字09和和11发生冲突:发生冲突: 因为两个数值都想要存因为
23、两个数值都想要存 放在表的第放在表的第4项中。项中。 分析分析 显然,当有元素发生冲突时,是无法进行直接显然,当有元素发生冲突时,是无法进行直接 查找的。所以引入查找的。所以引入Hash表表的概念:的概念: 设表的长度为设表的长度为n。若存在一个映象函数若存在一个映象函数i=i(k), 对于表中任一元素的关键字对于表中任一元素的关键字k,满足满足1 i(k) n ,则称此表为则称此表为Hash表表。并称。并称i(k)为关键字为关键字k 的的Hash码码。 Hash表中允许的冲突存在表中允许的冲突存在。如果在。如果在Hash表中表中 没有冲突存在,则没有冲突存在,则Hash表就成为直接查找表。表
24、就成为直接查找表。 分析分析 2. Hash表表 处理表中元素的主要工作:处理表中元素的主要工作: (1)构造合适的构造合适的Hash码,以便尽量减少表中元素冲突码,以便尽量减少表中元素冲突 的次数。的次数。 (2)当表中元素发生冲突时,要进行适当的处理。当表中元素发生冲突时,要进行适当的处理。 3. Hash码的构造码的构造 查找关键字为查找关键字为k的元素时,的元素时,计算计算Hash码码i(k)的工作量的工作量 是影响效率的重要因素是影响效率的重要因素。 在实际构造在实际构造Hash码时,要考虑如下两方面的因素:码时,要考虑如下两方面的因素: (1)使各关键字尽可能均匀地分布在使各关键字
25、尽可能均匀地分布在Hash表中,即表中,即 Hash码的均匀性要好,以便减少冲突发生的机会。码的均匀性要好,以便减少冲突发生的机会。 (2)Hash码的计算要尽量简单。码的计算要尽量简单。 一些简单的一些简单的Hash码构造方法码构造方法 截段法截段法 分段叠加法分段叠加法 除法除法 乘法乘法 截段法截段法 因为关键字是一种基本的符号串,而在计算机中因为关键字是一种基本的符号串,而在计算机中 就是一个经过编码的就是一个经过编码的二进制数字串二进制数字串。 截取法截取法:选取与关键字对应的数字串中的一段选取与关键字对应的数字串中的一段 (一般选取低位数)作为关键字的(一般选取低位数)作为关键字的
26、Hash码。码。 有有80个记录,关键字为个记录,关键字为8位十进制数,哈希地位十进制数,哈希地 址为址为2位十进制数。位十进制数。 8 1 3 4 6 5 3 2 8 1 3 7 2 2 4 2 8 1 3 8 7 4 2 2 8 1 3 0 1 3 6 7 8 1 3 2 2 8 1 7 8 1 3 3 8 9 6 7 8 1 3 6 8 5 3 7 8 1 4 1 9 3 5 5 . . 分析:分析: 只取只取8 只取只取1 只取只取3、4 只取只取2、7、5 数字分布近乎随机数字分布近乎随机 所以:取所以:取任意两位或两位任意两位或两位 与另两位的叠加作哈希地址与另两位的叠加作哈希地址
27、 举例举例: 关键字为关键字为 0442205864,哈希地址位数为,哈希地址位数为4 5 8 6 4 4 2 2 0 0 4 1 0 0 8 8 H(key)=0088 移位叠加移位叠加 5 8 6 4 0 2 2 4 0 4 6 0 9 2 H(key)=6092 间界叠加间界叠加 分段叠加法分段叠加法 将关键字的编码串分割成若干段,然后把它们叠加将关键字的编码串分割成若干段,然后把它们叠加 后再进行截段。后再进行截段。两种叠加处理的方法:两种叠加处理的方法: 移位叠加:移位叠加:将分割后的几部分低位对齐相加;将分割后的几部分低位对齐相加; 1.间界叠加:间界叠加:从一端沿分割界来回折送,
28、然后对齐相从一端沿分割界来回折送,然后对齐相 加。加。 除法除法 imod(k,n) 其中其中k为关键字,为关键字,n为为Hash表的长度,而表的长度,而mod为为 模余运算符模余运算符; 当当mod(k,n)=0时,取时,取i=n(本节规定)。本节规定)。 乘法乘法 imod(k*,n) 一般取一般取0.618033988747,或,或0.6125423371,或,或 0.6161616161。 3.2.2 几种常用的几种常用的Hash表表 1. 线性线性Hash表表 线性表是一种线性表是一种最简单的最简单的Hash表表。 设线性设线性Hash表的长度为表的长度为m,则对线性则对线性Hash
29、表的表的 查找过程如下:查找过程如下: 线性线性Hash表的填入表的填入 将关键字将关键字k及有关信息填入线性及有关信息填入线性Hash表的步骤如表的步骤如 下:下: 1)计算关键字计算关键字k的的Hash码码ii(k)。 2)检查表中第检查表中第i项的内容:项的内容: 若第若第i项为空,则将关键字项为空,则将关键字k及有关信息填入该及有关信息填入该 项;项; 若第若第i项不空,则令项不空,则令imod(i1,n),转转2)继继 续检查。续检查。 只要只要Hash表尚未填满,最终总可以找到一个空表尚未填满,最终总可以找到一个空 项,将关键字项,将关键字k及有关信息填入到及有关信息填入到Hash
30、表中。表中。 线性线性Hash表的表的 冲突处理。冲突处理。 线性线性Hash表的取出表的取出 要在线性要在线性Hash表中取出关键字表中取出关键字k的元素,其步骤的元素,其步骤 如下:如下: 1)计算关键字计算关键字k的的Hash码码ii(k)。 2)检查表中第检查表中第i项的内容:项的内容: 若第若第i项登记着关键字项登记着关键字k,则取出该项元素即可;则取出该项元素即可; 若第若第i项为空,则表示在项为空,则表示在Hash表中没有该关键表中没有该关键 字的信息;字的信息; 若第若第i项不空,且登记的不是关键字项不空,且登记的不是关键字k,则令则令i mod(i1,n)转转2)继续检查。继
31、续检查。 例例3.3 将关键字序列将关键字序列(09,31,26,19,01,13, 02,11,27,16,05,21)依次填入长度为依次填入长度为n12的的 线性线性Hash表中。表中。 设设Hash码码为为iINT(k/3)1。 表表3.2 线性线性Hash表表 分析分析 线性线性Hash表的表的优点优点:简单。简单。 线性线性Hash表的表的缺点缺点: 在线性在线性Hash表填入的过程中,当发生冲突时,首表填入的过程中,当发生冲突时,首 先考虑的是下一项,因此,当先考虑的是下一项,因此,当Hash码的冲突较多码的冲突较多 时,在线性时,在线性Hash表中会存在表中会存在“堆聚堆聚”现象
32、现象,即许,即许 多关键字被连续登记在一起,从而会降低查找效多关键字被连续登记在一起,从而会降低查找效 率。率。 在线性在线性Hash表的填入过程中,处理冲突时会带来表的填入过程中,处理冲突时会带来 新的冲突。线性新的冲突。线性Hash表的填入方法是表的填入方法是不顾后效不顾后效的。的。 n为为Hash表的长度,而表的长度,而m为为Hash表中实际存在的表中实际存在的 关键字个数。关键字个数。 注意注意:Hash表的平均查找次数表的平均查找次数E不依赖于表的长不依赖于表的长 度,而只与表的填满率有关。度,而只与表的填满率有关。 此公式只仅在知此公式只仅在知 道表长道表长n和实际填和实际填 放关
33、键字个数放关键字个数m的的 情况下有效!情况下有效! 如果有一个确定如果有一个确定 Hash表,则要确定表,则要确定 表的平均查找次数表的平均查找次数 就必须要采用就必须要采用平均平均 性态法性态法求取!求取! 2. 随机随机Hash表表 当当Hash表的长度表的长度n为为2的乘幂的乘幂时(时(n=2k),),可以可以 定义另一种定义另一种Hash表表随机随机Hash表表。 随机随机Hash表表与与线性线性Hash表表的不同之处在于:的不同之处在于: 一旦发生元素冲突时,表项序号一旦发生元素冲突时,表项序号i的改变不是的改变不是 采用加采用加1取模的方法,而是用某种取模的方法,而是用某种伪随机
34、数伪随机数来来 改变改变i值。值。 随机随机Hash表的填入表的填入 将关键字将关键字k及有关信息填入随机及有关信息填入随机Hash表的步骤如下:表的步骤如下: 1)计算关键字计算关键字k的的Hash码码i0i(k)。且令且令ii0。 2)伪随机数序列初始化,令伪随机数序列初始化,令j1(即将取随机数指针即将取随机数指针 指向伪随机数序列中的第指向伪随机数序列中的第1个随机数)。个随机数)。 3)检查表中第检查表中第i项的内容:项的内容: 若第若第i项为空,则将关键字项为空,则将关键字k及有关信息填入该项;及有关信息填入该项; 若第若第i项不空,则令项不空,则令imod(i0RN(j),n),
35、并令并令j j1(即将取随机数指针指向下一个随机数),即将取随机数指针指向下一个随机数), 转转3)继续检查。继续检查。 其中其中RN(j)表示伪随机数序列表示伪随机数序列RN中的中的第第j个随机数个随机数。 伪随机数的产生伪随机数的产生 伪随机数序列伪随机数序列RN按下列方法产生:按下列方法产生: R1 FOR j1 TO n DO Rmod(5*R,4n) RN(j)INT(R/4) 如果表的长度如果表的长度n=16,则伪随机数序列则伪随机数序列RN(j)为:为: 1,6,15,12,13,2,11,8,9,14,7, 随机随机Hash表的表长表的表长 例例3.4 将关键字序列将关键字序列
36、(09,31,26,19,01,13, 02,11,27,16,05,21)依次填入长度为依次填入长度为n24 16的随机的随机Hash表中。表中。 设设Hash码为码为iINT(k/3)1。 伪随机数序列为:伪随机数序列为: 1,6,15,12,13,2,11,8,9,14,7,4,5,10,3,0 表表3.3 随机随机Hash表(第表(第169页)页) 随机随机Hash表的取出表的取出 要在随机要在随机Hash表中取出关键字表中取出关键字k的元素,其步的元素,其步 骤如下:骤如下: 1)计算关键字计算关键字k的的Hash码码i0i(k)。且令且令ii0。 2)伪随机数序列初始化,令伪随机数
37、序列初始化,令j1(即将取随机数即将取随机数 指针指向伪随机数序列中的第指针指向伪随机数序列中的第1个随机数)。个随机数)。 3)检查表中第检查表中第i项的内容:项的内容: 若第若第i项登记着关键字项登记着关键字k,则取出该项元素即可;则取出该项元素即可; 若第若第i项空,则表示在项空,则表示在Hash表中没有该关键字信表中没有该关键字信 息;息; 若第若第i项不空,且登记的不是关键字项不空,且登记的不是关键字k,则令则令 imod(i0RN(j),n),并令并令jj1(即将取随即将取随 机数指针指向下一个随机数),转机数指针指向下一个随机数),转3)继续检查。继续检查。 其中其中RN(j)表
38、示伪随机数序列表示伪随机数序列RN中的第中的第j个随机数个随机数。 前两种前两种Hash表的缺点表的缺点 在在Hash表填入过程中表填入过程中不顾后效不顾后效,从而在填入过,从而在填入过 程中其冲突的机会在不断增多;程中其冲突的机会在不断增多; 当当Hash表表填满填满时,不能正常地进行查找。时,不能正常地进行查找。 解决方法解决方法:将冲突的元素安排在另外的空间内,将冲突的元素安排在另外的空间内, 而不占用而不占用Hash表本身的空间,则就不会产生新表本身的空间,则就不会产生新 的冲突。的冲突。 3. 溢出溢出Hash表表 溢出溢出Hash表包括表包括Hash表表和和溢出表溢出表两部分。两部
39、分。 在在Hash表的填入过程中,将冲突的元素表的填入过程中,将冲突的元素顺序填顺序填 入入溢出表,而当查找过程中发现冲突时,就在溢出表,而当查找过程中发现冲突时,就在 溢出表中进行顺序查找。溢出表中进行顺序查找。 溢出表是一个溢出表是一个顺序查找表顺序查找表。 溢出溢出Hash表的填入表的填入 将关键字将关键字k及有关信息填入溢出及有关信息填入溢出Hash表的步骤表的步骤 如下:如下: 1)计算关键字计算关键字k的的Hash码码ii(k)。 2)检查表中第检查表中第i项的内容:项的内容: 若第若第i项为空,则将关键字项为空,则将关键字k及有关信息填入该及有关信息填入该 项;项; 若第若第i项
40、不空,则将关键字项不空,则将关键字k及有关信息依次填及有关信息依次填 入溢出表中的入溢出表中的自由项自由项。 溢出溢出Hash表的取出表的取出 要在溢出要在溢出Hash表中取出关键字表中取出关键字k的元素,其步骤的元素,其步骤 如下:如下: 1)计算关键字计算关键字k的的Hash码码ii(k)。 2)检查表中第检查表中第i项的内容:项的内容: 若第若第i项登记着关键字项登记着关键字k,则取出该项元素即可;则取出该项元素即可; 若第若第i项为空,则表示在项为空,则表示在Hash表中没有该关键字表中没有该关键字 信息;信息; 若第若第i项不空,且登记的不是关键字项不空,且登记的不是关键字k,则转入
41、在则转入在 溢出表中进行溢出表中进行顺序查找顺序查找。 例例3.5 将关键字序列将关键字序列(09,31,26,19,01,13, 02,11,27,16,05,21)依次填入长度为依次填入长度为n12 的溢出的溢出Hash表中。表中。 设设Hash码为码为iINT(k/3)1。 表表3.4 Hash表和其溢出表(第表和其溢出表(第173页)页) 冲突的元素被填入冲突的元素被填入 溢出表的自由项溢出表的自由项 3.3 基本排序技术基本排序技术 排序:排序:将一个无序序列整理成将一个无序序列整理成按值非递减顺序按值非递减顺序 排列的有序序列。排列的有序序列。 本节所介绍的排序如不做特别说明一般认
42、为是本节所介绍的排序如不做特别说明一般认为是 顺序存储的线性表顺序存储的线性表,在程序设计语言中就是一,在程序设计语言中就是一 维数组。维数组。 3.3.1 冒泡排序与快速排序(互换排序)冒泡排序与快速排序(互换排序) 定义:定义:所谓互换排序是指借助数据元素之间的所谓互换排序是指借助数据元素之间的 互换进行排序的一种方法。互换进行排序的一种方法。 冒泡排序(冒泡排序(Bubble Sort)是一种最简单的互换是一种最简单的互换 排序,它是通过相邻两项目的比较,按一定次排序,它是通过相邻两项目的比较,按一定次 序互换,使表格逐步达到有序化。序互换,使表格逐步达到有序化。 快速排序(快速排序(Q
43、uick Sort)是对冒泡排序的一种是对冒泡排序的一种 改进。改进。 1. 冒泡排序冒泡排序 基本思想:基本思想: 首先对具有首先对具有n个项目的无序表进行扫描,比较相个项目的无序表进行扫描,比较相 邻两个元素的大小,若发现邻两个元素的大小,若发现逆序逆序则进行互换,则进行互换, 由此可以使由此可以使n个项目中的最大者沉到表的最后;个项目中的最大者沉到表的最后; 然后对剩下的未排序好的项目再进行扫描,使然后对剩下的未排序好的项目再进行扫描,使 它们之中的最大者又沉到表的最后;它们之中的最大者又沉到表的最后; 以此类推,直到将表全部排序好为止。以此类推,直到将表全部排序好为止。 说明说明:如果
44、每次扫描都将未排序序列中的最大元素沉如果每次扫描都将未排序序列中的最大元素沉 到表尾,则排序过程称为单向冒泡排序。如果每次不到表尾,则排序过程称为单向冒泡排序。如果每次不 仅向后扫描,而且同时向前扫描,将未排序序列中的仅向后扫描,而且同时向前扫描,将未排序序列中的 最小元素浮到表头,则排序过程称为双向冒泡排序。最小元素浮到表头,则排序过程称为双向冒泡排序。 大数在前,小大数在前,小 数在后!数在后! 首先,从表头开始往后扫描线性表,在扫描过程中逐次首先,从表头开始往后扫描线性表,在扫描过程中逐次 比较相邻两个元素的大小。若相邻两个元素中,前面的元比较相邻两个元素的大小。若相邻两个元素中,前面的
45、元 素大于后面的元素,则将它们互换,称之为素大于后面的元素,则将它们互换,称之为消去了一个逆消去了一个逆 序序。显然,在扫描过程中,不断地将两相邻元素中的大者。显然,在扫描过程中,不断地将两相邻元素中的大者 往后移动,最后就将往后移动,最后就将线性表中的最大者换到了表的最后线性表中的最大者换到了表的最后。 然后从后到前扫描剩下的线性表,同样,在扫描过程中然后从后到前扫描剩下的线性表,同样,在扫描过程中 逐次比较相邻两个元素的大小。若相邻两个元素中,后面逐次比较相邻两个元素的大小。若相邻两个元素中,后面 的元素小于前面的元素,则将它们互换,这样就的元素小于前面的元素,则将它们互换,这样就又消去了
46、又消去了 一个逆序一个逆序。显然,在扫描过程中,不断地将两相邻元素中。显然,在扫描过程中,不断地将两相邻元素中 的小者往前移动,的小者往前移动,最后就将剩下线性表中的最小者换到了最后就将剩下线性表中的最小者换到了 表的最前面表的最前面。 对剩下的线性表重复上述过程,直到剩下的线性表变空对剩下的线性表重复上述过程,直到剩下的线性表变空 为止,此时的线性表已经变为有序。为止,此时的线性表已经变为有序。(升序)(升序) 图图3.3 冒泡排序过程示意图(第冒泡排序过程示意图(第184页)页) 2. 快速排序快速排序 在冒泡排序中,每经过一次数据元素的互换只能在冒泡排序中,每经过一次数据元素的互换只能
47、移掉一个逆序。移掉一个逆序。 如果在排序过程中,每经过一次比较,使如果在排序过程中,每经过一次比较,使元素移元素移 动不止一个位置动不止一个位置,这就有可能同时移掉多个逆序,这就有可能同时移掉多个逆序, 达到加速排序的目的。达到加速排序的目的。 基本思想:基本思想:通过一趟分割将线性表分成两部分,通过一趟分割将线性表分成两部分, 其中前一部分的所有元素值其中前一部分的所有元素值均不大于均不大于后一部分中后一部分中 的每一个元素值;然后对每一部分在进行分割,的每一个元素值;然后对每一部分在进行分割, 直到整个线性表有序为止。直到整个线性表有序为止。 具体做法具体做法 从线性表中选取一个元素,设为
48、从线性表中选取一个元素,设为T。然后将线性然后将线性 表表后面小于后面小于T的元素移到前面的元素移到前面,而,而前面大于前面大于T的元的元 素移动到后面素移动到后面,结果就将线性表分成了两部分,结果就将线性表分成了两部分 (两个子表),而(两个子表),而T插入到其分界线的位置处。插入到其分界线的位置处。 该过程被称为该过程被称为线性表的分割线性表的分割。 如果对分割后的各子表再按上述原则进行分割,如果对分割后的各子表再按上述原则进行分割, 并且这种分割过程可以一直做下去,直到所有子并且这种分割过程可以一直做下去,直到所有子 表为空为止,则此时的线性表就变成了表为空为止,则此时的线性表就变成了有
49、序表有序表。 通过一趟分割将线性表分成两部分,其中前一部通过一趟分割将线性表分成两部分,其中前一部 分的所有元素值分的所有元素值均不大于均不大于后一部分中的每一个元后一部分中的每一个元 素值;素值; 快速分割示意图快速分割示意图 首先,在表的首先,在表的第一个第一个、中间一个中间一个与与最后一个最后一个元素中元素中 选取选取中项中项,设为,设为L(k),并将并将L(k)赋给赋给T,再将表中再将表中 的第一个元素移到的第一个元素移到L(k)的位置上。的位置上。 然后设置两个指针然后设置两个指针i和和j分别指向表的起始与最后的分别指向表的起始与最后的 位置。反复作以下两步:位置。反复作以下两步:
50、(1)将将j逐渐减小,并逐次比较逐渐减小,并逐次比较L(j)与与T,直到发现一直到发现一 个个L(j)T为止,为止,将将L(j)移到移到L(i)的位置上的位置上。 (2)将将i逐渐增大,并逐次比较逐渐增大,并逐次比较L(i)与与T,直到发现一直到发现一 个个L(i)T为止,为止,将将L(i)移到移到L(j)的位置上的位置上。 上述两个操作交替进行,直到指针上述两个操作交替进行,直到指针i与与j指向同一个指向同一个 位置(即位置(即ij)为止,此时将为止,此时将T移到移到L(i)的位置上。的位置上。 快速排序的过程快速排序的过程 初始关键字初始关键字 k i j 一次交换一次交换 ij 二次交换
51、二次交换 i j 三次交换三次交换 ij 四次交换四次交换 i j 完成一趟排序完成一趟排序 ij 3.3.2 简单插入排序与希尔排序简单插入排序与希尔排序 1. 简单插入排序简单插入排序 基本思想:基本思想:依次将线性表中的每一个元素插入到一依次将线性表中的每一个元素插入到一 个已经有序的子表中。个已经有序的子表中。 方法:方法: 将线性表中,将线性表中,只包含第只包含第1个元素的子表个元素的子表显然可以显然可以 看成是有序表;看成是有序表; 从线性表的从线性表的第第2个元素开始直到最后一个元素个元素开始直到最后一个元素, 逐次将其中的每一个元素插入到前面已经有序的逐次将其中的每一个元素插入
52、到前面已经有序的 子表中;子表中; 一般来说,假设线性表中前一般来说,假设线性表中前j-1个元素已经有序,个元素已经有序, 现在要现在要将线性表中第将线性表中第j个元素插入到前面的有序子个元素插入到前面的有序子 表表中。中。 5 5 1 7 3 1 6 9 4 2 8 6 1 7 3 1 6 9 4 2 8 6 j j2 2 1 1 5 5 7 3 1 6 9 4 2 8 6 7 3 1 6 9 4 2 8 6 j j3 3 1 5 1 5 7 7 3 1 6 9 4 2 8 6 3 1 6 9 4 2 8 6 j j4 4 1 1 3 3 5 7 5 7 1 6 9 4 2 8 6 1 6
53、9 4 2 8 6 j j5 5 1 1 1 1 3 5 7 3 5 7 6 9 4 2 8 6 6 9 4 2 8 6 j j6 6 红色的部分红色的部分:有序子表;:有序子表;绿色的部分绿色的部分:之前插入的数字:之前插入的数字 1 1 3 5 1 1 3 5 6 6 7 7 9 4 2 8 6 9 4 2 8 6 j j7 7 1 1 3 5 6 7 1 1 3 5 6 7 9 9 4 2 8 6 4 2 8 6 j j8 8 1 1 3 1 1 3 4 4 5 6 7 9 5 6 7 9 2 8 6 2 8 6 j j9 9 1 1 1 1 2 2 3 4 5 6 7 9 3 4 5
54、6 7 9 8 6 8 6 j j1010 1 1 2 3 4 5 6 7 1 1 2 3 4 5 6 7 8 8 9 9 6 6 j j1111 1 1 2 3 4 5 6 1 1 2 3 4 5 6 6 6 7 8 9 7 8 9 红色的部分红色的部分:有序子表;:有序子表;绿色的部分绿色的部分:之前插入的数字:之前插入的数字 #include using namespace std; template void insort( T p , int n ) int j, k; T t; for ( j=1; j=0 ) k = k 1; pk+1 = t; return; 数组数组p,存放
55、着待排序列存放着待排序列 数组数组p的长度,即待排的长度,即待排 序序列中元素的个数序序列中元素的个数 简单插入排序简单插入排序 当前待排序列(从当前待排序列(从 pj到到pn-1)中第中第 一个元素的值赋给一个元素的值赋给t 将待排序列中第一个元将待排序列中第一个元 素素t插入到已排序序列中插入到已排序序列中 的合适位置,同时保证的合适位置,同时保证 已排序序列仍旧为升序已排序序列仍旧为升序 序列序列 2. 希尔排序希尔排序 直接插入排序的时间复杂度为直接插入排序的时间复杂度为O(n2),但是若但是若 待排记录序列为待排记录序列为“正序正序”时,其时间复杂度可时,其时间复杂度可 以提高至以提
56、高至O(n)。 由此可以设想:由此可以设想: 若待排记录序列按关键字若待排记录序列按关键字“基本有序基本有序”,直,直 接插入排序的效率就可大大提高;接插入排序的效率就可大大提高; 一方面,由于直接插入排序算法简单,则在一方面,由于直接插入排序算法简单,则在 n值很小时效率也比较高。值很小时效率也比较高。 希尔排序的希尔排序的基本思想基本思想:先将整个待排记录序列分割先将整个待排记录序列分割 成为成为若干个子序列分别进行直接插入排序若干个子序列分别进行直接插入排序,待整个,待整个 序列中的记录序列中的记录“基本有序基本有序”时,再对全体记录进行时,再对全体记录进行 一次直接插入排序。一次直接插
57、入排序。 子序列的分割方法如下:子序列的分割方法如下: 将将物理位置上物理位置上相隔某个增量相隔某个增量h的元素构成一个子的元素构成一个子 序列。序列。 在排序过程中,逐次减小这个增量,最后当在排序过程中,逐次减小这个增量,最后当h减减 到到1时,进行一次插入排序,排序就完成。时,进行一次插入排序,排序就完成。 增量序列一般取增量序列一般取 htn/2k(k1,2,log2n), 其中其中n为待排序序列的长度。为待排序序列的长度。 图图3.6 希尔排序示意图(第希尔排序示意图(第191页)页) 希尔排序的希尔排序的C+描述描述 #include using namespace std; tem
58、plate void shel(T p, int n) int k,j,i; T t; k=n/2; while (k0) for (j=k; j=0) i=i-k; pi+k=t; k=k/2; return; 3.3.3 简单选择排序与堆排序简单选择排序与堆排序 1. 简单选择排序简单选择排序 基本思想:基本思想:扫描整个线性表,从中选出最小的扫描整个线性表,从中选出最小的 元素,将它交换到表的最前面;然后对剩下的元素,将它交换到表的最前面;然后对剩下的 子表采用同样的方法,直到子表空为止。子表采用同样的方法,直到子表空为止。 简单选择排序在最坏情况下需要比较:简单选择排序在最坏情况下需要
59、比较: 2/ )1( nn 图图3.7 简单选择排序例(第简单选择排序例(第192页)页) 2. 堆排序堆排序 堆的定义:堆的定义:具有具有n个数据元素的序列(个数据元素的序列(h1, h2, , hn),),当且仅当满足:当且仅当满足: 12 2 ii ii hh hh 12 2 ii ii hh hh 知识回顾知识回顾:如将一棵有如将一棵有n个结点的个结点的完全二叉树完全二叉树自顶向下,自顶向下, 同一层自左向右连续给结点编号同一层自左向右连续给结点编号 1, 2, , n,则有以下则有以下 关系:若关系:若i = 1, 则则i无双亲;若无双亲;若i 1, 则则i的双亲为的双亲为i /2;
60、 若若2i n, 则则i无左孩子;否则,无左孩子;否则,i的左孩子为的左孩子为2i;若若2i+1 n, 则则i无右孩子;否则,无右孩子;否则,i的右孩子为的右孩子为2i+1。 完全二叉树完全二叉树 顺序表示顺序表示 hi h2i & hi h2i+1 完全二叉树完全二叉树 顺序表示顺序表示 hi h2i & hi h2i+1 09 87 78 456531 23 53 17 09 877845 65 3153 23 17 09 17 65 23 45 78 87 53 31 87 78 53 45 65 09 31 17 23 1 2 3 4 5 6 7 8 9 对应的对应的 数组:数组: 小
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2023年枣庄市市中区光明路街道城乡公益性岗位招聘考试真题
- 2023年乐山市沐川县教育局教师考试真题
- 贷款签约合同范本
- 2024年工程制图教案创新设计研究
- 2024年PIE工程师培训教程:人工智能应用
- 2024商业协议模板规范
- 2024年度高品质玉米购销协议
- 2024年委托人力资源服务协议
- 餐饮业运营承包协议基本格式2024
- 2024年冷链物流运输服务协议
- 高三一本“临界生”动员会课件
- 家长会课件:四年级家长会语文老师课件
- 食堂验收记录表
- 水利工程生产安全重大事故隐患判定标准(修订稿)
- 血液净化标准操作规程
- 我家乡宜兴介绍课件
- 4.2+酶催化细胞的化学反应(教学课件)-【知识精讲精研】高一生物 (沪科版2020必修1)
- 森林资源概况课件
- 胰腺癌的影像学表现课件
- 电梯维保报价单【模板】
- 2023年四川凉山州木里重点国有林保护局招聘18人笔试备考试题及答案解析
评论
0/150
提交评论