7 查找 (1)
-
Upload
wylie-hancock -
Category
Documents
-
view
48 -
download
2
description
Transcript of 7 查找 (1)
数据结构 ---查找
7 7 查找查找 (1)(1)
数据结构 ---查找
1 、掌握查找的概念,熟练掌握顺序表和有序表(折半查找)的查找算法及其性能分析方法;
2 、掌握二叉排序树的概念,熟练掌握二叉排序树的构造和查找算法及其性能分析方法;
3 、掌握二叉排序树的插入算法,二叉排序树的删除方法;4 、掌握平衡二叉树的概念,掌握平衡化二叉树的方法;5 、掌握哈希查找的概念,掌握哈希函数(除留余数法)的构
造。6 、掌握用线性探测法和链地址法解决冲突的方法,并能进行
查找长度的计算。7 、熟悉标准模版库 STL 中的相关知识。
1 、掌握查找的概念,熟练掌握顺序表和有序表(折半查找)的查找算法及其性能分析方法;
2 、掌握二叉排序树的概念,熟练掌握二叉排序树的构造和查找算法及其性能分析方法;
3 、掌握二叉排序树的插入算法,二叉排序树的删除方法;4 、掌握平衡二叉树的概念,掌握平衡化二叉树的方法;5 、掌握哈希查找的概念,掌握哈希函数(除留余数法)的构
造。6 、掌握用线性探测法和链地址法解决冲突的方法,并能进行
查找长度的计算。7 、熟悉标准模版库 STL 中的相关知识。
教学目标
数据结构 ---查找
7.1 静态查找表7.2 动态查找表7.3 哈希表(散列表)7.4 查找与标准模版库 STL
7.1 静态查找表7.2 动态查找表7.3 哈希表(散列表)7.4 查找与标准模版库 STL
教学内容
数据结构 ---查找
问题一 高考招生工作结束了,学校在第一时间
公布了已经被录取的学生的准考证号码和姓名。但由于数量太多,肉眼很难查看。因此,学校的招生网往往会允许考生根据自己的准考证号码 , 来查看是否已被录取。
网站一般是如何根据输入的准考证号码来实现快速查找的呢?
数据结构 ---查找
问题二 手机的使用者会经常更新手机中的通讯
录。当接听或拨打朋友的电话时,会检查这个朋友的号码是否已经存在自己手机的通讯录中,若有必要就会将该号码添加到通讯录中。
系统如何快速查找某个号码,以及是如何在通讯录中添加号码的?查找和添加的效率如何?
数据结构 ---查找
相关知识
数据结构 ---查找
什么是查找表 ?由相同类型的数据元素 ( 或记录 ) 构成的集
合称作查找表。其元素之间无明确的关系。
问题一的已录取的学生信息和问题二的通讯录均属查找表。
相关知识一
数据结构 ---查找
对查找表经常进行的操作 :
1 )查询某个数据元素是否在查找表中;2 )在查找表中插入一个数据元素;3 )从查找表中删去某个数据元素。
相关知识二
问题一和问题二均需要进行查找。问题二还需要插入或删除。
数据结构 ---查找
静态查找表:仅作查询或检索操作的查找表。
动态查找表:有时在查询之后,还需要将“查找失败”的数据元素插入到查找表中;或者从查找表中删除其指定的数据元素。
查找表的一般分类 :
问题一和问题二分属静态查找表和动态查找表。
相关知识三
数据结构 ---查找
是数据元素(或记录)中某个数据项的值,用以标识某个数据元素(或记录)。
相关知识四
问题一的准考证号码属于关键字。问题二的电话号码属于关键字。
什么是关键字?
数据结构 ---查找
在查找表中确定是否存在一个数据元素,该元素的关键字等于给定的某个值。 若查找表中存在这样的元素,则“查找成功”。否则“查找失败”。
相关知识五
问题一:准考证号出现在查找表中表示成功。问题二:电话号码出现在通讯录中表示成功。
查找成功和失败的依据是什么?
数据结构 ---查找
查找的方法取决于查找表的结构。采用不同的存储结构将导致不同的查找效率。 因此,采用合适的数据结构来表示查找表是非常重要的。
如何进行查找 , 效率如何?
问题一的准考证号可以用(有序)数组存放。问题二的电话号码可以用二叉(排序)树存放。
相关知识六
数据结构 ---查找
7.1 静 态 查 找 表一、顺序查找表
二、有序查找表
数据结构 ---查找
数据对象 D :
数据关系 R :
具有相同特性的数据元素的集合。含有类型相同的关键字,可唯一标识数据元素。 数据元素同属一个集合。
ADT StaticSearchTable {
Create(&ST, n); // 构造Destroy(&ST); // 销毁Search(ST, key); // 查询Traverse(ST, Visit()); // 遍历
基本操作 P :
} ADT StaticSearchTable
数据结构 ---查找
通常以顺序表或线性链表表示静态查找表。
一、顺序查找表
数据结构 ---查找
静态查找表的顺序存储结构为struct SSTable{
ElemType *elem; // 元素存储空间基址, 0 号单元留空 int length; // 表的长度};
数据元素的类型定义为 :struct ElemType{
keyType key; // 关键字 … … // 其它属性可选} ;
数据结构 ---查找
21 37 88 19 92 05 64 56 80 75 13 0 1 2 3 4 5 6 7 8 9 10 11
ST.Length
ST.elem
顺序表的查找过程:
假设给定值 e=64,
要求 ST.elem[k] = e, 问 : k = ?
k=7
数据结构 ---查找
int Location(SSTable ST, KeyType e) // 正向查找{
k = 1;while ( k<=ST.length && ST.elem[k]!=e) k++;
if ( k<= ST.length) return k;
else return 0;
} //Location
数据结构 ---查找
21 37 88 19 92 05 64 56 80 75 13 0 1 2 3 4 5 6 7 8 9 10 11
ST.Length
ST.elemi
21 37 88 19 92 05 64 56 80 75 13 0 1 2 3 4 5 6 7 8 9 10 11
ST.Length
ST.elem
i
60
i
key=64
key=60
i
64
从尾端往前查,并且初始设置 ST.elem[0]=key( 称作哨兵pivot)
数据结构 ---查找
int Search_Seq(SSTable ST, KeyType keyV) { // 在顺序表 ST 中顺序查找其关键字等于 key 的数据元素。 // 若找到,则返回该元素在表中的位置,否则为 0 。 ST.elem[0].key = keyV; // “ 哨兵” // 从后往前找 for (i=ST.length; ST.elem[i].key!=keyV; i--) ; return i; // 找不到时, i 为 0
} // Search_Seq
本方法的时间复杂度和前者相同,但由于避免了下标越界的比较,实际效果还是不错的。
数据结构 ---查找
定义: 查找算法的平均查找长度 (Average Search Length)
为确定记录在查找表中的位置,需和给定值进行比较的关键字个数的期望值
其中 : n 为表长, Pi 为查找表中第 i 个记录的概率,且 , Ci 为找到该记录时,已经的比较次数。
分析顺序查找的时间性能
n
iiiCPASL
1
11
n
iiP
数据结构 ---查找
在等概率查找的情况下, 顺序表查找的平均查找长度为:
对顺序表而言, Ci = n-i+1 (逆向查找)
nPi
1
2
11
1
1
n)i(n
nASL
n
iss
ASL = nP1 +(n-1)P2 + …… +2Pn-1+Pn
Sequence Search
这里只考虑查找成功的代价
数据结构 ---查找
若考虑查找不成功时的情况:查找不成功时的比较次数: n+1 假设有一半情况查找失败,则兼顾查找成功和失败平均查找长度为:
)1(4
3)1(
2
1)1(
2
1
11
nnn
inn
ASLn
i
n
iss
今后,一般仅讨论查找成功时的平均查找长度和查找不成功时的比较次数,但哈希表例外。
此处说明查找失败需要花费更多的代价
数据结构 ---查找
顺序查找表的查找算法简单,但平均查找长度较大,效率较低。
二、有序查找表
若以有序表表示静态查找表,则查找过程可以基于“折半”进行。 (又称二分查找 )
数据结构 ---查找
折半查找的基本思想 折半查找:先计算查找区域正中间对象的下
标 mid ,用其关键字与给定值 x 比较 : elem[mid].key = x ,查找成功,结束查找; elem[mid].key > x ,把查找区间缩小到表的前半部
分,再继续进行折半查找; elem[mid].key < x ,把查找区间缩小到表的后半部
分,再继续进行折半查找。
每比较一次,查找区间缩小一半。若最后的查找区间为空,则查找失败。
数据结构 ---查找
05 13 19 21 37 56 64 75 80 88 92 0 1 2 3 4 5 6 7 8 9 10 11
ST.elemST.length
例如 : key=64 的查找过程如下:
low highmid
low mid
high
mid
low 指示查找区间的下界high 指示查找区间的上界mid = (low+high)/2
数据结构 ---查找
int Search_Bin ( SSTable ST, KeyType keyV) { low = 1; high = ST.length; // 置区间初值 while (low <= high) { mid = (low + high) / 2; if (keyV == ST.elem[mid].key ) return mid; // 找到待查元素 else if (keyV < ST.elem[mid].key) high = mid - 1; // 继续在前半区间进行查找 else low = mid + 1; // 继续在后半区间进行查找 } return 0; // 顺序表中不存在待查元素} // Search_Bin
数据结构 ---查找
先看一个具体的情况,假设: n=11分析折半查找性能
63 9
1 4
2 57
810
11
判定树
i 1 2 3 4 5 6 7 8 9 10 11Ci 12 23 3 3 34 4 4 4
数据结构 ---查找
为讨论方便,设 n=2h-1 ,且查找概率相等则 在 n>50 时,可得近似结果
显然,表长为 n 的折半查找的判定树的深度和含有 n 个结点的完全二叉树的深度相同。
1)1(log1
211
21
1
1
nn
nj
nC
nASL
h
j
jn
iibs
1)1(log2 nASLbs
详细推导过程请参见课本或其他材料
数据结构 ---查找
平均查找长度 大 (n) 小 (logn)
逻辑结构 有序表、无序表 有序表
存储结构 顺序存储结构,或线性链表
顺序存储结构
静态查找方法比较顺序查找 折半查找
数据结构 ---查找
让事实说话
快乐学习在线判题( Happy Learn Online Judge )
数据结构 ---查找
在线练习一:高考录取查询(8871~8873) Problem Description 高考招生结束了,你已经在第一时间获得了学校公布的已经被录取的全部N个准考证编号。
你的M个朋友 , 他们希望你能帮他们查一下 ,看看他们是否已被录取 . 由于朋友数量太多,因此你不得不编写一个程序来完成这个任务。注意 ,这些朋友委托你查询的编号可能重复。
数据结构 ---查找
Input输入数据的第一行为一个整数 N(N 不超过10000) ,表示有 N个准考证编号 . 这些准考证编号的范围在 1 到 200000 之间。然后是一个整数 (M 不超过 10000) ,表示提供M个准考证编号,请你分别统计录取和未录取的数量。
Output分别输出录取和未录取的人数。
Sample Input42 4 6 131 3 1
Sample Output2 1
数据结构 ---查找
开始在线测试……
数据结构 ---查找
在线测试截图(高考录取查询)
数据结构 ---查找
测试结果(高考录取查询)单位 ms 表长
10000表长100000
表长1000000
无序顺序表 78 828 10265
有序顺序表 0 78 750
请考虑哪些因素会影响测试效果?
大规模数据的输入耗时? 系统的测试误差?
其他因素?
数据结构 ---查找
在线练习二:小明的通讯录 (8874~8876) Problem Description 小明上中学了,为了方便和家里以及同学联系,爸爸给小明买了一台手机。该手机的存储容量可以扩充,因此,可存储的电话号码数量没有限制。
小明的手机有一个特殊的功能,对于打进或拨出的新号码,手机均会自动进行储存。给出小明的新手机在一个月内使用的通讯记录,请你回答此时此刻小明的手机中存储了多少个电话号码。
数据结构 ---查找
Input输入数据的第一行为一个整数 N( N 不超过 10000) ,表示后面有 N个电话号码。为方便处理,假设电话号码的长度是 5 位数,也就是范围在 10000 到 99999 之间。
Output输出小明的手机中存储的电话号码总数。
Sample Input7 1000002 3000004 9000002 10000021000011 1234567 1000002
Sample Output5
本问题应考虑哪些因素?
静态查找表能否达到目的?查找表如何扩充,采用的方法和效率?
数据结构 ---查找
(n)
(1)
(n)
(1)
结合前面刚学的知识以及对插入和删除操作的分析,这里我们给出小结 :
查找 插入 删除无序顺序表 无序线性链表有序顺序表 有序线性链表
(n)
(n)
(logn
)
(n)
(1)
(1)
(n)
(1)
注意,这里的插入和删除是在查找后进行的。
数据结构 ---查找
1 )从查找性能看,最好情况能达 (logn) ,此时要求逻辑结构有序;
2 )从插入和删除的性能看,最好情况能达 (1) ,此时要求存储结构是链表。
结论:
给我们的启发:若需要动态维护查找表,应该采用链式存储结构,且元素有序。
数据结构 ---查找
在线测试截图(小明的通讯录)
数据结构 ---查找
测试结果(小明的通讯录)
单位 ms 规模10000
规模100000
规模1000000
无序顺序表 46 2781 超时
有序顺序表 31 1687 超时
二叉排序树 0 140 2125
哈希表 0 62 718
数据结构 ---查找
小结 引入了查找表 介绍了查找表的概念 分别讨论了顺序查找和折半查找在静态查
找表中应用。 分析了顺序查找和折半查找的 ASL 。 利用在线测试总结和验证了顺序查找和折半查找的性能。
数据结构 ---查找
课后任务 复习总结静态查找表的知识 预习动态查找表的有关内容(重点预习平衡二叉树)