顺序查找:
(1)应用范围:顺序表或线性链表表示的静态查找表,表内元素是无序的。
(2)数据元素的定义:一个元素下有多个数据项,但其中必有一个用于查找的关键字域。以成绩单为例,会有姓名成绩和学号等。
typedef struct {
KeyType key; //关键字
...... //其他信息
}ElemType;
(3)表的定义:将所有元素以数组的形式集合就成了一个顺序表。
typedef struct{ //顺序表结构类型定义
ElemType *R; //表的地址
int length; //表长
}SSTable;
SSTable ST; //定义顺序表
(4)顺序查找就是遍历数组,看数组元素里有没有一个数据项等于关键字的元素,另外数组下标为0的位置一般不用。
int Search_Seq(SSTable ST,KeyType key){
//从后往前找,若成功返回其位置,否则返回0
for(i=ST.length;i>=1;--i){
if(ST.R[i].key==key) return i;
return 0;
}
}
//其他形式
int Search Seq(SSTable ST,KeyType key){
for(i=ST.length;ST.R[i].key!=key&&i>0;i--);
if(i>0) return i;
else return 0;
}
以上方法每次循环要进行两次比较(比较是否是关键字和i是否小于等于0)。
改进:设哨兵。将待查关键字存在数组下标0的位置(即表头),从后往前找,若没有最终也会返回0,从而免去比较i的步骤。
int Search_Seq(SSTable ST,KeyType key){
ST.R[0].key=key;
for(i=ST.length;ST.R[i].key!=key;--i);
return i;
}
(5)时间效率分析:比较次数与key的位置有关。从后往前找,查找第i个元素需要比较n-i+1次,查找失败的情况下需要比较n+1次。时间复杂度为O(n)(可以用期望衡量),设每个元素被查找的概率相同,则查找成功时的
ASL=(1+2+3+...+n)/n=(n+1)/2
在查找概率不相等的情况下可以按查找概率高(比较次数少)的放在后面,低(比较次数多)的放前面的方式存储以提高查找效率。
在查找概率无法测定的情况下,按查找概率动态调整元素顺序以提高查找效率,即在元素的定义中再设一个访问频度,一次查找后访问频度发生变化,始终保持访问频度高的在后,每次查找后将刚查到的元素放到表头。