算法——查找

        查找,在当今大数据时代是十分频繁需要进行的操作,在数据库软件中也是非常重要的功能之一,所以,一个好的查找算法也够大大节省计算机资源以及节省时间,大大提高效率。

下面将分别介绍顺序查找、二分查找和哈希查找算法

#define LEN 10
#define swap(a,b) {typeof(a) t=a;a=b;b=t;}
#define show_arr(arr,len) {for(int i=0;i<len;printf("%d ",arr[i++]));}
1、顺序查找

顺序查找,即对待查找的数据没有要求,从头到尾逐一比较,在小规模的查找中较为常见,查找效率较低。时间复杂度:O(N)

//顺序查找
int order_search(int *arr,int len,int key)
{
	for(int i=0;i<len;i++)
	{
		if(key==arr[i])
			return i;
	}
	return -1;
}
2、二分查找(折半查找)

待查找的数据必须有序,从数据中间位置开始比较查找,如果中间值比key小,则从左边继续进行二分查找,反之从右边进行。时间复杂度:O(logN)

因为二分查找要求数据是有序的所以这里我们顺便写个冒泡排序,用来保证传入的数列有序

//排序
void sort(int *arr,int len)
{
	for(int i=0;i<len-1;i++)
	{
		for(int j=i+1;j<len;j++)
		{
			if(arr[j]<arr[i])
			{
				int temp=arr[i];
				arr[i]=arr[j];
				arr[j]=temp;
			}
		}
	}
}

//二分查找循环
int bin_search(int *arr,int len,int key)
{
	sort(arr,len);
	if(key>arr[len/2])
	{
		for(int i=len/2+1;i<len;i++)
		{
			if(key==arr[i]) return i;	
		}
	}
	else if(key<arr[len/2])
	{
		for(int i=0;i<len/2;i++)
		{
			if(key==arr[i]) return i;	
		}
	}
	else if(key==arr[len/2])
		return len/2;
	return -1;
}

//二分查找递归法
int _digui_search(int *arr,int l,int r,int key)
{
	if(l>r) return -1;
	int m=(l+r)/2;
	if(arr[m]==key) return m;
	if(key<arr[m]) return _digui_search(arr,l,m-1,key);
	else return _digui_search(arr,m+1,r,key);
}
int digui_search(int *arr,int len,int key)
{
	return _digui_search(arr,0,len-1,key);
}
3、块查找(权重查找)

是一种数据处理的思想,不是一种特定的算法,当数据量非常多时,可以先把数据进行分块处理,然后再根据分块的条件进行查找,例如英文字典。

4、哈希查找(Hash)

数据 经过 哈希函数 计算出数据在哈希表中的位置,然后标记位置,方便之后的查找,它的时间复杂度最高可以达到 O(1)
        但是该算法有很大的局限性,不适合负数、浮点型数据、字符型数据的查找,还需要额外申请存储空间,空间复杂度高,是一种典型的以空间换时间的算法
    哈希函数设计方法:
        直接定址法:直接把数据当做哈希表的下标,把哈希表中该下标的位置+1
        数据分析法:分析数据的特点来设计哈希函数,常用的方法是找到最大值和最小值,用 最大值-最小值+1 确定哈希表的长度,使用 数据-最小值 作为哈希表的下标访问哈希表
        平方取中法、折叠法、随机数法,但都无法保证哈希数据的唯一性,出现所谓的哈希冲突,一般使用链表解决
    Hash函数的应用:MD5、SHA-1都属于Hash算法中的应用

//哈希查找
int hash_search(int *arr,int len,int key)
{
	//直接定址法
	//创建哈希表
	/*int hash[100000]={};
	for(int i=0;i<len;i++)
	{
		hash[arr[i]]++;	
	}
	return hash[key];*/
	int max=arr[0],min=arr[0];
	for(int i=1;i<len;i++)
	{
		if(arr[i]>max) max=arr[i];
		if(arr[i]<min) min=arr[i];
	}
	//创建哈希表
	int hash[max-min+1];
	memset(hash,0,sizeof(hash));
	for(int i=0;i<len;i++)
	{
		hash[arr[i]-min]++;	
	}
	//查找
	return key-min;
}

测试一下各个算法:

int main(int argc,const char* argv[])
{
	int arr[LEN]={};
	for(int i=0;i<LEN;i++)
	{
		arr[i]=rand()%100;
		printf("%d ",arr[i]);
	}
	printf("\n");
	//printf("order search:%d\n",order_search(arr,LEN,77));
	//sort(arr,LEN);
	printf("循环二分:%d\n",bin_search(arr,LEN,92));
	printf("递归二分:%d\n",digui_search(arr,LEN,92));
	//for(int i=0;i<LEN;i++) printf("%d ",arr[i]);
	show_arr(arr,LEN);
	printf("\n");
	printf("%d\n",hash_search(arr,LEN,49));

	return 0;
}

简单介绍一下以上查找算法以及其代码实现

over

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值