临阵磨枪,不快也光。本文主要内容数据结构C语言版线性表查询
顺序查找
顺序查找适合于存储结构为顺序存储或链接存储的线性表,时间复杂度为O(n),空间复杂度:O(1)
#include <stdio.h>
void orderFind(int a[],int len,int key){
for(int i=0;i<len;i++){
if(a[i]==key){
printf("找到key为%d的值了,在数组第%d位\n",a[i],i+1);
return;
}
}
printf("查找失败!");
return;
}
int main()
{
int arr[]={545,983,0,387,345,897,612};
int len=sizeof(arr)/sizeof(arr[0]);
orderFind(arr,len,545);
return(0);
}
折半查找(二分查找)
简单来说就是每次都取中间值,将查找的值与中间值作比较。如果相等直接输出。否则,缩小范围,继续查找。代码里设有左右两个标记/指针(分别在第一位和最后一位),如果中间值大于查找值则转移大指针至中间值位置的前一位(左一位),如果小于查找值则将小指针转移至中间值位置的右一位(后一位)。在这里主要注意的有两点:一是必须采用顺序存储结构,一是表中元素按关键字有序排列,必须有序。时间复杂度:O(),空间复杂度:O(1)
注:折半查找的前提条件是需要有序表顺序存储,对于静态查找表,一次排序后不再变化,折半查找能得到不错的效率。但对于需要频繁执行插入或删除操作的数据集来说,维护有序的排序会带来不小的工作量,那就不建议使用。——《大话数据结构》
代码:
#include <stdio.h>
void binarySearch(int a[],int len,int key){
int low=0,high=len-1;
printf("func形参arr的长度:%d,len的长度:%d\n",sizeof(a),sizeof(a)/sizeof(a[0]));
/*
* 数组作为函数参数传入函数的过程中会“退化”为指针,
* 因此求出的是一个指针的内存空间大小,而非数组的内存空间大小,所以计算的长度错误
* 也因此不要用此方法求形参数组的长度
*/
while(low<high){
int mid=(low+high)/2;
if(key>a[mid]){//key在中间值的右侧
low=mid+1;
}else if(key<a[mid]){//key在中间值的左侧
high=mid-1;
}else if(key==a[mid]){//相等
printf("查找成功,a[%d]=%d",mid,key);
return;
}
}
printf("查找失败");
return;
}
int main()
{
int arr[]={5,13,19,21,37,56,64,75,80,88,92};
/* C语言无法直接获取数组长度,
* 但可以用sizeof()关键字获取数组实际可存放元素个数(不是数组存放了多少元素)
* 同样,用sizeof 也可以获得整个数组在内存中所占的字节数。 因为数组中每个元素的类型都是一样的,
* 在内存中所占的字节数都是相同的,所以总的字节数除以一个元素所占的字节数就是数组的长度
*/
int len=sizeof(arr)/sizeof(arr[0]);
printf("数组arr的长度len:%d \n",len);
int a=21;
binarySearch(arr,len,a);
return 0;
}
//标准输出:
//数组arr的长度len:11
//func形参arr的长度:8,len的长度:2
//查找成功,a[3]=21
索引查找
索引查找又称分块查找,是一种介于顺序查找和二分查找之间的一种查找方法。
基本思想是:首先查找索引表,可用二分查找或顺序查找,然后在确定的块中进行顺序查找。
#include <stdio.h>
struct index{//定义索引表结构
int key;
int start;
int end;
}indexTable[0];
void indexSeach(int a[],int key,int len){
int i=0;
while(i<len&&key>indexTable[i].key){//寻找目标数据所在的块
i++;
}
if(i>=len){//目标数据不在数组分的块里
printf("您要寻找的值“%d”在数组中不存在!",key);
return;
}
for(int j=indexTable[i].start;j<=indexTable[i].end;j++){
if(a[j]==key){
printf("key-%d找到啦,在索引表第%d块,在数组第%d位\n",key,i,j);
return;
}
}
printf("key-%d没有找到\n",key);
return;
}
int main()
{
int arr[]={5,13,19,21,37,56,64,75,80,88,92};//主表
int len=sizeof(arr)/sizeof(arr[0]);
int j=0,i;//j:记录while循环几次,i:用来表示区块的上下标
int block=3;
while(i<len){//创建索引表
j++;
i+=1;
indexTable[j].start=i;
i=i+block>len?len:i+block;//增加判断,防止数组越界
indexTable[j].end=i;
indexTable[j].key=arr[i==len?i-1:i];//如果i=len;下标需要减一,增加判断,防止数组越界
printf("%d,%d,%d\n",indexTable[j].start,indexTable[j].end,indexTable[j].key);
}
int key=75;
indexSeach(arr,key,j);
int key1=77;
indexSeach(arr,key1,j);
int key2=127;
indexSeach(arr,key2,j);
return 0;
}
/*
* 1,4,37
* 5,8,80
* 9,11,92
* key-75找到啦,在索引表第2块,在数组第7位
* key-77没有找到
* 您要寻找的值“127”在数组中不存在!
*/