记录的逻辑顺序与其在计算机存贮器中存储顺序一致的表,称为 顺序表 。
顺序查找的基本思想:
从表的一端开始,顺序扫描线性表,依次将扫描到的结点关键宇和给定值K相比较。若当前扫描到的结点关键字与K相等,则查找成功;若扫描结束后,仍未找到关键字等于K的结点,则查找失败。a
(1)类型说明
int maxsize = 100 ; //数据表的最大长度
typedef int KeyType //关键字的类型
struct datalist
{ KeyType key ;
char ch ;
//… //其他域
};
datalist[maxsize] ;
(2)具体算法
void sequence_search(KeyType K,datalist r[],int n)
{ int i=0;
r[n].key=K;
while(r[i].key!=K)i++;
if(i<n)cout<<"查找成功,该记录对应的下标为:"<<i<<endl;
else cout<<"查找失败!"<<endl;
}
算法分析:
(1) 在最坏的情况下,顺序查找需要比较 n 次,即 MSL = n 。
(2) 假定各记录的查找机会均等,即 P i = 1/n ,由于查找第 i 个记录需要比较 i 次,即 C i = i ,于是有:

这样,最大查找长度和平均查找长度的数量级 ( 即算法的时间复杂度 ) 均为 O(n) 。
顺序查找的优点和缺点
优点:算法简单,且对表的结构无任何要求,无论是用向量还是用链表来存放结点,也无论结点之间是否按关键字有序,它都同样适用。
缺点:查找效率低,因此,当n较大时不宜采用顺序查找。
有序表的查找
对于以数组方式存贮的记录,如果数组中各个记录的次序是按其关键字值的大小顺序排列的,则称为有序数组或有序表。
折半查找
对顺序分配的有序表可以采用折半查找 (Binary Search) ,又称二分查找。
1.基本思想
从第 1 个记录开始逐个顺序搜索,而是每次把要找的给定值 K ,与在中间位置的记录的关键字值进行比较。设有序记录数组 r 中每个记录的关键字值按升序排列为:
r 0. key , r 1.key , r 2.key ,…, r m.key ,…,r n-1.key
其中, n 为记录个数。当 i < j 时,有 r i.key ≤ r j.key 。开始时,中间位置记录的序号为 m = [(n + 1)/2] ,相应的关键字值为 r m.key 。将给定值 K 与 r m.key 比较,有三种可能的结果:
(1) K = r m.key
查找成功,结束查找。
(2) K < r m.key
由于各记录的关键字值是由小到大排列的,因此,如果要查找的记录存在,必定在有序表的左半部分。于是,对左半部分继续使用折半查找进行搜索,但搜索区间缩小了一半。
(3) K > r m.key。
如果要查找的记录存在,则必定在有序表的右半部分于是,对右半部分继续使用折半查找进行搜索,但搜索区间缩小了一半。
这样在查找过程中,搜索区间不断对分并成指数地缩小,因而查找速度明显地快于顺序查找。当最后只剩下一个记录,而且此记录不是要找的记录,则宣告查找失败。
2.折半查找的算法
void binary_search(KeyType K,datalist r[],int n,)
{ int m,low ,high,find;
low=0;high=n-1;find=0;
do{ m=(low+high)/2;
if(K==r[m].key)
{ cout<<"查找成功,该记录对应的下标为:"<<m<<endl;
find=1;
}
else if(K<r[m].key)high=m-1;
else low=m+1;
}while((find==0)&&(low<=high));
if(find==0)cout<<"查找失败!\n";
}
|