下面就三种常见的查找算法(顺序查找、二分查找、分块查找)进行总结并附实现代码,代码已验证。
1、顺序查找
基本思想:顺序查找顾名思义就是按顺序挨个查找
时间复杂度:O(n)
算法分析:简单易懂,对查找序列也没啥要求,对于很多杂乱无章的字符串,常用这种算法,但效率低下
实现代码:
int OrderSearch(int *p, int n,int key)
{
int i;
for(i=0; i<n; i++)
{
if(p[i] == key)
return i;
}
return -1;
}
2、二分查找法
基本思想:二分查找也称折半查找,利用序列元素直接的有序性,采用分治策略,将n个元素的序列以a[n/2]为界分成两部分,如果关键字(要查找的元素)=a[n/2]则key的位置就是n/2,如果key<a[n/2]则在小于a[n/2]的区间内继续查找,如果大于a[n/2]则在大于a[n/2]的区间内继续查找。如此反复查找,只要序列中存在key就一定能查找。
时间复杂度:O(log(n))
算法分析: 此算法比较次数少,速度较快,但要求查找序列必须是有序的
实现代码:用递归和非递归两种方法实现
int Bsearch_rec(int *p, int s, int e, int ch)//利用递归recursion
{
int mid ;
if(s > e)
{
return -1;//-1表示没找到或者输入有误
}
mid = (s + e) / 2;
if(p[mid] == ch)
return mid;
if(ch < p[mid])
return Bsearch_rec(p, s, mid-1, ch);
else
return Bsearch_rec(p, mid+1, e, ch);
}
int Bsearch_nonrec(int *p, int s, int e, int ch)
{
int mid ;
while(s <= e)
{
mid = (s + e) / 2;
if(ch == p[mid])
return mid ;
else if(ch < p[mid])
e = mid-1;
else
s = mid + 1;
}
if(s > e)
return -1;
}
3、分块查找
基本思想:又称索引顺序查找,其是对顺序查找的一种改进。先将n个数据元素按块有序(前一块的任一元素都比当前块的任一元素小),所谓块其实就是一个区间,块必须有序,但块内可以无序。步骤就是先成m块(m<=n),然后再对每个块进行顺序查找。
实现代码:
typedef struct BlockIndex
{
int start;//块的起始位置
int end;//结束位置
int key;//块中最大值
}BlockIndex;//分为4块
BlockIndex blockind[4];
int BlockSearch(int *p, int n,int des)
{
int i = 0;
int j;
while(i <= 3 && des > blockind[i].key)
i++;
if(i>3)
return -1;
else
{
for(j=blockind[i].start; j<=blockind[i].end; j++)
{
if(des == p[j])
return j;
}
return -1;
}
}
综上所述,二分查找或者分块查找,都需要一定的条件,而实际序列往往是不能满足,所以最常用的还是顺序查找,其他两个只能看场合使用