在日常生活中,人们几乎每天都在进行各种各样的查找工作。例如,在电话号码薄中查找电话号码;在字典中查阅词汇等。
在程序设计中,特别是对于非数值处理语言,要消耗大量的时间进行查找运算,而且由于查找运算的频率很高,几乎在任何一个计算机系统软件和应用软件中都会涉及。当问题涉及的数据量相当大的时候,查找方法的效率就显得格外重要,在一些实时应答系统中尤其如此。所以,一个好的查找方法会大大提高程序及系统的效率和速度。
①查找又称检索,是数据处理中经常使用的一种重要运算。
②在本章的讨论中,假定被查找的对象是一组结点组成的表或文件,而每个结点由若干个数据项组成,并假设每个结点都有一个能唯一标识该结点的关键字。在这种假定下,查找的定义是:给定一个值k的结点,若找到,则查找成功,输出该结点在表中的位置;否则查找失败,输出失败的信息。
③因为查找是对已存入计算机中的数据所进行的操作,所以,采用何种查找方法,首先取决于使用哪种数据结构来表示表,即表中的数据元素按何种方式组织。为了提高查找速度,常常用某些特殊的数据结构组织存储表。因此,在研究各种查找方法时,首先必须弄清这些方法所使用的数据结构。
④查找有内查找和外查找之分。若整个查找过程都在内存中进行,则称为内查找;反之,若查找过程需要访问外存,则称为外查找。
① 数据项:项是具有独立含义的标识单位,是数据不可分割的最小单位
② 组合项:组合项由若干项组合而成
③ 数据元素:数据元素是由若干项、组合项构成的数据单位,是在某一问题中作为整体进行考虑和处理的基本单位。数据元素有型和值之分,表中项名的集合,也即表头部分就是数据元素的类型。
④ 关键字:关键字是数据元素中某个项或组合项的值,用它可以标识一个数据元素。能唯一确定一个数据元素的关键字,称为主关键字;而不能唯一确定的一个数据元素的关键字,称为次关键字。
⑤ 查找表:查找表是由具有同一类型的数据元素组成的集合。分静态查找表和动态查找表。
①顺序查找是一种最基本也是最简单的查找方法。它的基本思想是,从表的一端开始,顺序扫描整个线性表,逐个进行结点关键字值与给定的值k相比较,若当前扫描到的结点关键字与k相等,则查找成功;若扫描了整个表后,仍未找到关键字与给定值k相等的结点,则查找失败。
②顺序查找方法既适用于线性表的顺序存储结构,也适用于线性表的链式存储结构。使用单链表作为存储结构时,查找必须从头指针开始,因此只能进行顺序查找。下面介绍顺序表作为存储结构时的顺序查找。
③基本类型的具体算法:
typedef struct{
KeyType key; //关键项
Datatype other; //其他域
}SSTable;
SSTable R[MAX]; //约定从下标1开始存放查找表元素,0单元闲置
④基于顺序表的顺序查找算法
int SeqSearch(SSTable R[],int n,KeyType k){
int i=n;
R[0].key=k;
while(R[i].key!=k){
i--;
}
return i;
}
①二分查找又称为折半查找,是一种效率较高的查找方法。但是,二分查找要求线性表是有序表,即表中的数据元素按关键字有序组织,并且要用顺序表作为表的存储结构。在下面的讨论中,假设顺序表是有序递增的。
②二分查找的基本思想是,首先将待查找的k值和有序表R中间位置mid=(1+n)/2上的结点的关键字进行比较:
(1)若相等,则查找完成
(2)若R[mid].key>k,则说明待查找的结点在表的前半部分,可在前半部分表中继续进行二分查找。
(3)若R[mid].key
③这样,经过一次关键字的比较就缩小一半查找区间;如此反复,直到找到关键字为k的结点(查找成功),或当前的查找区间为空(查找失败)。
④二分查找算法
int BinSearch(table R[],int n,KeyType k){
int low,mid,high;
low=1; //设置查找的上下区间
high=n;
while(low<=high){ //当前查找区间为非空
mid=(low+high)/2;
if(k==R[mid].key)
return mid; //查找成功返回在表中的位置
if(khigh=mid-1; //缩小查找区间为左子表
else
low=mid+1; //缩小查找区间为右子表
}
return 0; //查找失败
}
①分块查找又称索引顺序查找,是一种性能介于顺序查找和二分查找之间的查找方法。它要求按如下的索引方式来存储查找表:将表均分为b块,前b-1块中的结点数为S=[n/b],第b块的结点数小于等于S;每一块中的关键字不一定有序,但前一块中的最大关键字必须小于后一块中的最小关键字,即要求表是“分块有序”的;抽取各块中的最大关键字及其块起始位置构成一个索引表ID[b],即ID[i]中存放着第i块的最大关键字及该块在表R中的起始位置。由于表R是分块有序的,所以索引表是一个递增的有序表。
②分块查找的基本思路是,首先,查找索引表,因为索引表是有序表,故可采用二分查找或顺序查找,以确定待查找的结点在哪块;然后,在已确定的块中进行顺序查找。
③分块查找的优点是,在表中插入或删除一个记录时,只要找到该记录所属的块,就在该块中进行插入或删除运算。因块内记录的存放是任意的,所以,插入或删除比较容易,无须移动大量记录。分块查找的主要代价是需要增加一个辅助数组存储索引表和对初始表进行分块排序建立索引表的运算。