1、静态查找 不改变数据信息
2、查找的性能
查找成功时的平均查找长度(ASL):定值与关键字进行比较的次数的期望值
线性查找
1、思想:从线性表的一端开始,顺序扫描线性表,依次将扫描到的
结点关键字与给定值k相比较。
若当前扫描到的结点关键字与k相等,则查找成功;
若扫描结束后,仍未找到关键字等于k的结点,则查找失
败。
在a[0]放置需要查找的值,这样省去了判断越界
2、平均查找次数(n+1)/2
时间复杂度O(n)
3、适合小型数据的查找(避免查找n次的情况)
#include<stdio.h>
#include<stdlib.h>
int search(int *a,int last,int key)
{
int i;
a[0]=key; //把需要查找的值放a[0]里
i=last;
while (a[i]!=key) //从最后循环,避免了判断前后越界的问题
{
i--;
}
return i;
}
//链表
typedef struct searchlink
{
int data;
struct searchlink *next;
}searchlink;
searchlink* search2(searchlink* T,int key)
{
searchlink* p=T;
while(p!=NULL)
{
if(p->data==key)
return p;
else
p=p->next;
}
return p;
}
int main()
{
int a[10]={1,5,3,8,6,4,2,99,35,24};
int k=search(a,9,2);
if(k==0)
printf("查找失败\n");
else
printf("第几个:%d 值为%d\n",k+1,a[k]);
return 0;
}
折半(二分)查找
1、前提:线性表中的记录是有序的(从小到大)
一定是有序的!!!
2、查找过程:先找中间的元素,如果小 找左边中间的元素比较;比中间的数值大->找右边中间的元素比较。 mid=(low+last)/2
3、时间复杂度 : O(log2 n)
完整代码
#include<stdio.h>
#include<stdlib.h>
//非递归实现
int binsearch(int key,int length,int *a)
{
int up,mid,low;
low=1; up=length;
while (low <= up)
{
mid=(low+up)/2;
if(key<a[mid])
up=mid-1;
else if(key>a[mid])
low=mid+1;
else
return mid;
}
return 0;
}
//递归实现
int bin_search(int *a,int low,int up,int key)
{
if(low>up)
return 0;
else{
int mid=(low+up)/2;
if(key==a[mid])
return mid;
else if(key<a[mid])
bin_search(a,low,mid-1,key);
else
bin_search(a,mid+1,up,key);
}
}
int main()
{
int a[10]={1,2,3,8,16,24,28,99,135,224};
int k=binsearch(16,10,a);
printf("第几个:%d 值为%d(非递归)\n",k+1,a[k]);
int t=bin_search(a,1,10,8);
printf("第几个:%d 值为%d(递归)\n",t+1,a[t]);
return 0;
}
分块查找
1、思想:均匀分块(每块的数据个数相同)、块间有序、块内无序。
建立块索引:存放每块最大的关键字
先确定 查找的k 可能出现的块号,然后在块中顺序查找
2、性能:
ASL=(数据总个数/块数+块数)/2+1
时间复杂度 O(n)
int index_search(int key,int last,int blocks,int *indexi,int *listi,int L) //listi是整个数据表,indexi是索引表
{
int i=0,j;
while((key>indexi[i])&&(i<blocks)) //查找块
i++;
if(i<blocks)
{
j=i*L; //起始下标
while((key !=listi[j])&&(j<=(i+1)*L-1)&&(j<last)) //块内顺序查找
j++;
if(k == listi[j]) //查找成功
return j;
}
return -1; //查找失败
}