目录
一. 前言
查找表:由同一类型的数据元素(或记录)构成的集合。
查找:根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素或记录。
关键字:用来标识一个数据元素或记录的某个数据项的值。其中可唯一地标识一个记录的关键字是主关键字,反之,用以识别若干记录的关键字是次关键字。
查找表可分为两类:静态查找表和动态查找表。其中,静态查找表为仅做“查询”操作的查找表,动态查找表能够做插入和删除操作的查找表。
现在我们要讲的顺序查找就是一种静态查找表,另外静态查找表还有折半查找和分块查找。
二. 顺序查找表
顺序查找的应用范围:顺序表或线性链表表示的静态查找表,并且表内元素之间无序。
也就是说当表内元素无序的时候,就比较适合采用顺序查找。
下面我们来看下顺序查找表的结构定义,如下所示:
typedef struct{
KeyType key; //关键字域,如果还有其他域可自行加上
}ElemType;
typedef struct{
ElemType * R; //顺序查找表的基地址
int length; //表长
}SSTable; //Sequential Search Table
其中,如KeyType等类型的名字都是可以由自己定义的数据类型,根据关键字的类型确定。
在定义好了顺序查找表之后就可以通过顺序查找表来顺序查找一个关键字,主要思路就是,从顺序查找表中的最后一个元素开始查找,如果找到和关键字相同的元素,那么就返回位置信息,否则返回0。代码实现如下所示:
int Search_Sq(SSTable ST,KeyType key){
for(int i=ST.length;ST.R[i].key!=key;--i){
if(i<=0) break; //如果一直没有查找到,那么i的值就会小于等于0,这时候就要退出循环了
if(i>0) return i; //如果i大于0,表示找到,返回i的位置
else return 0; //没找到就返回0
}
注意:我们顺序查找表里面位置序号为0的地方一般是不存放元素的。
通过观察分析我们可以发现,上面这段代码每次都需要比较两次,一次比较就是比较关键字跟给定值是不是相同,另外一次比较就是比较这个i是否大于0。因此我们可以根据这个来优化代码,思路就是利用空出来的0号位置,将它设置为一个哨兵,如下所示:
int Search_Sq(SSTable ST,KeyType key){
ST.R[0].key=key; //把要查找的给定值设置为哨兵,存放到0号位置
for(int i=ST.length;ST.R[i].key!=key;i--){
return i; //即使顺序查找表中没有这个给定值,最后这个for循环也会返回一个值,就是0
}
}
不管是否查找到,返回到的值都是我们想要的,返回0我们就知道了它没查找到。这样就不再需要比较它是否大于0了。
三. 顺序查找的算法分析
顺序查找的时间复杂度为O(n),空间复杂度为O(1)。
我们还可以采取以下措施来提高顺序查找的算法效率:
当我们知道其中记录的查找频率,那我们就可以把查找频率高的放在后面,这样比较次数就会减少。
顺序查找的特点:1)算法简单,逻辑次序无要求,且不同存储结构均适用。2)平均查找长度ASL太长,时间效率太低。