第3章 查找与排序1
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1.线性哈希表
线性哈希表的构造 (1)计算元素k的哈希码i=i(k) (2)检查表中第i项的内容: *若第i项为空,则将元素k填入该位置。 *若第i向不空,则令i=mod(i+1,n), 转(2)继续检查。
例如:将线性表 (9,31,26,19,1,13,2,11,27,16,5,21)依次 填入长度n=12的线性哈希表中,哈希函数为 i=INT(k/3)+1,其中INT为取整符。 线性哈希表 表项序号 1 2 3 4 5 6 7 8 9 10 11 12 元素值k 1 2 5 9 13 11 19 16 26 27 31 21 冲突次数 0 1 1 0 0 2 0 2 0 0 0 4
在线性哈希表中查找元素k (1)计算元素k的哈希码i=i(k) (2)检查表中第i项的内容: *若第i项内容为k,则取出该元素值即可 *若第i向为空,则表示在哈希表中没有 该元素。 *若第i项不空,且其内容不是k,则令 i=mod(i+1,n),转(2)继续检查。
2. 随机哈希表 长度为n=2a
low
int bsearch(ET v[],int n,ET x){ low=1;high=n; while(low<=high){ mid=(low+high)/2; if(v[mid]==x) return mid; if(v[mid]<x) low=mid+1; else high=mid-1; } return -1;
哈希码构造常用的几种方法
1.除法
哈希码i=mod(k,n) 2.乘法 哈希码i=mod(k* ,n)
几种常用的哈希表
哈希表技术关键之一就是要处理好冲突问 题。采用不同的方法处理冲突就可以得到 不同的哈希表。常用的有: 1.线性哈希表 2. 随机哈希表 3.溢出哈希表 4.拉链哈希表 5.指标哈希表
其中,CH1 表示元素中第1 个字母,Ord 为字符的次序 函数。则以表长为14的顺序 表表示的查找表如图
0 1 Chen 2 Dei 3 4 Han 5 6 Li 7 8 Qian 9 Sun 10 11 Wu 12 Ye 13 Zhao
上例表为直接查找表,其满足以下条件: 设表的长度为n,如果存在一个函数i=i(k), 对于表中的任意一个元素值k,满足: (1)1<=i<=n; (2)对于任意元素值k1=k2,都存在i(k1)=i(k2).
第3章
查找与排序技术
3.1 基本的查找技术 3.2 哈希表技术 3.3 基本的排序技术 3.4 二叉排序树及其查找
3.1 基本的查找技术
查找是数据处理领域的一个重要内容, 查找的效率将直接影响到数据处理的 效率。所谓查找是指在一个给定的数 据结构中查找指定的元素。通常,根 据不同的数据结构应采用不同的查找 方法。
3.2 哈希表技术
哈希表技术是一种重要的查找技术,其基 本思想是对被查元素做某种运算后直接确 定其在表中的位置。所以哈希查找方法是 用元素值进行计算元素存储位置的查找方 法。
元素在表中的位置为该元素的某个函数, 通常称这种函数为“哈希函数”或“哈希码”
例如,对于关键字序列 { Zhao,Qian,Sun, Li,Wu,Chen,Han,Ye,Dei }, 可设关键字的哈希函数如下: i(k)=[(ord(CH1)-ord(‘A’)+1)/2]
1
6
7
18
22 12 13 8 9 20 33 42 44 38 24 46 60 58 74 47 86 53 i j i=1; if((low!=high)&&(x>s[low].key)) j=n; if(high!=m&&x>s[low].key) if(high!=m) else j=s[high].k-1;
key k
存放子表中的最大值 子表中第一个元素在 线性表中的位序
在分块有序表查找元素的过程: (1) 首先可利用对分查找在索引表中确 定被查元素所在的子表。 (2) 再用顺序查找法在相应子表中进行 查找。 索引表 struct indnode{ ET key; 最大值 22 46 86 int k; 1 7 13 起始位序 };
high
}
3.1.3. 分块查找
分块查找又称索引顺序查找,用于在 分块有序表中进行查找。
分块有序表是将线性表分成子表,要求后 一个子表的元素大于前一个子表的元素。
22 12 13 8 9 20 33 42 44 38 24 46 60 58 74 47 86 53
分块有序表
分块有序表的结构分为两部分 (1)线性表本身采用顺序存储结构 (2)建立一个索引表。为每个子表建立 一个索引结点:
在哈希码比较均匀且冲突不多的情况下,溢 出哈希表具有一定的适用价值。
4.拉链哈希表
拉链哈希表分为外拉链哈希表和内拉 链哈希表,这里介绍外拉链哈希表。 外拉链哈希表由哈希表及表外结点组成。 将哈希码相同的结点连接成单链表,单链 表的头指针就存放在哈希表中。 例如:将线性表 (9,31,26,19,1,13,2,11,27,16,5,21)依次 填入长度n=12的外链哈希表中,哈希函数为 i=INT(k/3)+1,其中INT为取整符。
k
c head
e
b
d 0
顺序查找数据元素b
3.1.2. 有序表的对分查找
有序表的对分查找只适用于顺序存 储的有序表,即线性表中的元素按 值非递减排列。
25 查找元素 24
mid
1 2 3 4 5 6 7 8 9 10 11 12 13 2 5 7 9 12 15 17 19 24 28 30 34 36
哈希表技术需要处理好冲突问题,主要包 括以下两方面工作: (1)哈希码的均匀性要比较好。即尽量减 少元素冲突的次数。 (2)当表中发生冲突是要进行适当的处理。
哈希码的构造
哈希表技术的主要目标是提高查找效率, 因此在实际设计哈希码是主要考虑: (1)哈希码的均匀性要好。即尽量减少冲 突发生的机会,使元素尽可能均匀地分布 在哈希表中。 (2) 哈希码的计算要尽量简单。
例如:将线性表 (9,31,26,19,1,13,2,11,27,16,5,21)依次 填入长度n=12的溢出哈希表中,哈希函数为 i=INT(k/3)+1,其中INT为取整符。 溢出哈希表 i 1 2 3 4 5 6 7 8 9 10 11 12 哈希表 k 1 5 9 13 16 19 21 26 27 31 i 1 2 3 4 溢出表 k 2 11
return k; }
顺序查找缺点:对于大的线性表来说 效率低。
顺序查找优点:算法简单而且适用面广, 适用于: (1)线性表为无序表时 (2)有序表采用链式存储结构时。
在头指针为head的线性链表中顺序查找元 素x,函数返回被查找元素x所在结点的存 储地址。
node* lsearch (node* head, ET x ){ node k=head; while(k!=NULL&&k->data!=x) k=k->next; return k; }
1 6 7 12 13 18
22 12 13 8 9 20 33 42 44 38 24 46 60 58 74 47 86 53
分块有序表
47 8 查找元素 38
mid 22 1
low
46 7
86 13
high
12 13
struct indnode{ ET key; int k; }; indnode s[m];
(1)计算元素k的哈希码i0=i(k),且i=i0
构 (2)伪随机序列初始化,令j=1,即发生冲 突时从伪随机序列第一个开始试探。 造 (3)检查表中第i项的内容: 过 *若第i项为空,则将元素k填入该位置。 程 *若第i向不空,则令
i=mod(i0+RN(j),n),并令j=j+1,即取下 一个随机数进行试探,转(3)继续检查。
i=s[high].k; j=s[high+1].k-1;
int insearch(ET v[],int m,int n,ET x,indnode s[]){ //分块有序表v,长度为n,索引表数组s的结点数m,查找x low=1;high=m; while(high-1>low){//对分查找索引表 mid=(low+high)/2; if(x<=s[mid].key) high=mid; else low=mid;} i=1; //i是所在子表的起始位序 if((low!=high)&&(x>s[low].key)) i=s[high].k; j=n; //j是所在子表的终止位序 if(high!=m&&x>s[low].key) j=s[high+1].k-1; else j=s[high].k-1; while((i<=j)&&(v[i]!=x)) i++; if(i>j) i=-1; return i; }
例如:将线性表 (9,31,26,19,1,13,2,11,27,16,5,21)依次 填入长度n=16的随机哈希表中,哈希函数为 i=INT(k/3)+1,其中INT为取整符。
位随机序列为: 1,6,15,12,13,2,11,8,9,14,7,4,5,10,3,0
表项序号 元素值k 冲突次数
1 1 0
3.1 基本的查找技术
3.1.1. 顺序查找 3.1.2. 有序表的对分查找 3.1.3. 分块查找
3.1.1. 顺序查找
顺序查找是指在线性表中查找指定的元素, 其基本方法为:从线性表的第一个 元素开始,依次将线性表中的数据元素 与被查元素进行比较,若相等则表示找 到;如果线性表中所有的元素都与被查 找元素进行了比较但都不相等,则查找 失败,即表中没有要找的元素。
学习要求
1.熟练掌握顺序表和有序表的链式存 储结构的顺序查找方法; 2.熟悉掌握有序表的对分查找方法; 3.了解分块有序表的分块查找方法; 4.熟练掌握常用哈希表的构造方法,深刻 理解哈希表与其它结构的表的实质性的差别;
作业: 3.6, 3.10
2 2 1
3 5 1
4 5 6 7 8 9 13 16 19 21 0 0 0 0 0
表项序号 9 10 11 12 13 14 15 16 元素值k 26 11 31 27 冲突次数 0 2 0 2
3.溢出哈希表
溢出哈希表处理冲突的策略是将发 生冲突的元素安排另外的空间内, 则就不会产生新的冲突,这就是溢 出表。所以溢出哈希表包括哈希表 和溢出表两部分。
但直接查找表的哈希函数是不容易构造的, 在实际应用中,往往会出现不同的元素值 k1!=k2,会有i(k1)!=i(k2),这就发生了元素 的冲突,即两个不同的元素需要存放在同 一个存储位置上。
哈希表:设表的长度为n,如果存在一个 例如:线性表 函数i=i(k),对于表中的任意一个元素k (9,31,26,19,1,13,2,11,27,16,5,21)依次 均满足1<=i<=n,则称此表为哈希表。 填入长度n=12的表中,哈希函数为 函数i=i(k)称为哈希码或哈希函数。 i=INT(k/3)+1,其中INT为取整符。 哈希表 填入结果 表项序号 1 2 3 4 5 6 7 8 9 10 11 12 9 13 16 19 21 26 27 31 按i=INT(k/3)+1 1 5 填入的元素值 2 11
外 拉 链 哈 希 表
1 2 3 4 5 6 7 8 9 10 11 12
1 2
0
0 0 0 0 0 0 0 0 0
5
0
11 9 13 16 19 21 26 27 31
0
5.指标哈希表
当表中各数据元素的类型不同,即 长度不相等时,则哈希表表项的空 间设计很困难,如果都按最大长度 设计,则会造成存储空间浪费。在 这种情况下,需要用指标哈希表。 指标哈希表包括指标表与内容表。
k
顺序查找数据元素 b h
e a w c b m p g
1 2 3 4 5 6 7 8
int search(ET V[],int n,ET x){
在线性表V中查找 其元素等于给定值 x的数据元素,若 找到,则返回其在 V中的下标,否则 返回-1。 k=1; while(k<=n)andV(k)!=x) k++; if(k==n+1) k=-1;ቤተ መጻሕፍቲ ባይዱ