【数据结构】查找

临阵磨枪,不快也光。本文主要内容数据结构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(\log_{2}n),空间复杂度: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”在数组中不存在!
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值