查找算法(部分)

 

顺序查找

顺序查找是最简单的了,属于无序查找算法,它的原理就是从前往后一个一个的找,如果找到了就返回它的位置,否则就返回-1。

如果有多个相同元素的话,返回第一个该元素的位置。

代码:

#include<stdio.h>
#define N 100
int main()
{
	int a[N],n,x;//x表示要查找的元素 
	scanf("%d %d",&n,&x);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	int j;
	for(j=0;j<n;j++)
	{
		if(a[j]==x)//如果找到直接跳出循环 
		break;
	}
	if(j>=n)
	{
		printf("-1");//如果没找到就返回-1 
	}
	else
	{
		printf("%d ",j+1);//返回它的位置,即是第几个元素 
	}
	return 0;
} 

运行:

 20200302101449382.png

二分查找

二分查找(Binary Search)算法,也叫折半查找算法,针对有序查找算法(即只适用于有序序列的查找)。它的原理就是每次都通过跟区间的中间元素对比,将待查找的区间缩小为之前的一半,直到找到要查找的元素,或者区间被缩小为 0。

代码:

#include<stdio.h>
#define N 100
int main()
{
	int a[N],n,x;//x表示要查找的元素 
	scanf("%d %d",&n,&x);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	int left=0,right=n-1,mid;
	while(left<=right)
	{
		mid=(left+right)/2;
		if(x==a[mid]) break;
	    if(x>a[mid]) 
	    {
		    left=mid+1;
	    }
	    else
	    {
		    right=mid-1;
	    }
    }
	if(left>right)
	{
		printf("-1");//如果没找到就返回-1 
	}
	else
	{
		printf("%d ",mid+1);//返回它的位置,即是第几个元素 
	}
	return 0;
} 

运行:

 20200302112325645.png

插值查找

插值查找就是二分查找的改进,其算法思路是一样的,只不过二分查找是每次是从数组的中间位置查找的,但是如果能在查找前较准确地预测关键字在数组中的位置的话,效率就会大大提高。

插值查找其核心就在于插值的计算公式key-arr[left]/arr[right]-arr[left]。细看是不是key在整序列中的占比哟。所以mid的计算公式为 left+(right-left)*(key-arr[left])/(arr[right]-arr[left])。对比二分查找的mid = (right-left)/2。

举个例子来理解一下:1 2 3 4 5 6 查找元素3

使用插值查找公式:0 +(5-0)*(3-1)/(6-1)=2,这样的话一次就找到了,效率要高于二分查找。

对表长较长,且关键字分分布比较均匀,插值查找算法的平均性能要比二分查找要好的多。但是 如果表中 关键字分布极端不均匀 那么插值查找还不如折半查找呢。

代码和折半查找一模一样,唯独mid的计算方式发生改变。

代码:

#include<stdio.h>
#define N 100
int main()
{
	int a[N],n,x;//x表示要查找的元素 
	scanf("%d %d",&n,&x);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a[i]);
	}
	int left=0,right=n-1,mid;
	while(left<=right)
	{
		mid=left+(right-left)*(x-a[left])/(a[right]-a[left]);
		if(x==a[mid]) break;
	    if(x>a[mid]) 
	    {
		    left=mid+1;
	    }
	    else
	    {
		    right=mid-1;
	    }
    }
	if(left>right)
	{
		printf("-1");//如果没找到就返回-1 
	}
	else
	{
		printf("%d ",mid+1);//返回它的位置,即是第几个元素 
	}
	return 0;
} 

运行:

 20200302190652883.png

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值