查找算法c语言实验报告,C语言实现各大查找算法(一)

这篇博客介绍了如何使用C语言实现三种查找算法:顺序查找、折半查找(二分查找)和插值查找。顺序查找的时间复杂度为O(n),适用于小规模数据。折半查找利用了二分思想,效率较高,时间复杂度为O(log2n)。插值查找在有序数组中尝试更接近目标值的位置查找,最佳情况下的时间复杂度为O(log2(log2n))。文章还探讨了这些算法的适用场景和优缺点。
摘要由CSDN通过智能技术生成

@C语言实现各大查找算法(一)

直 奔 主 题 !!!

今天用c语言实现数据结构中的查找算法,我们先实现顺序查找、折半查找(二分查找)、插值查找算法,后续我们会实现其他的查找算法。(主要是咱也还不会啊…)

先附上题目,有如下数组,我们随便给个值,查找一下里面有没有和这个值相同的,如果有,输出它的下标,也就是位置。(我们假定数组是从小到大排序的,且只有一个答案,此外,数组元素、数组长度、查找的key值,都可以从控制台输入,没啥大问题)

FnlUFrb0NHd-mkKLh8sJpM0Ho6rS

num = 30;

顺序查找(linear search)

顺序查找比较简单,从数组下标 0 到 数组长度-1 一一遍历过去,找到就输出下标,不然就一直遍历,直到数组遍历结束,它的时间复杂度为 O(n) 。过程如下图:

Fumv-nV6a_nIula0G3_Hr9Mpx8UC代码实现如下:

1 int linearSearch(int arr[],int len,int num) {

2 int i = 0;

3 for(i = 0;i < len;i++) {

4 if(arr[i] == num) {

5 return i;

6 }

7 }

8 return 0;

9 }

由于简单,没有什么特别需要注释的,看懂就好,虽然也没啥人看,我好难啊…

折半查找(二分查找 binary search)

对于一些数组长度较长的数组,顺序查找显然不适用了,要是重复的数在最后一位,啧啧,电脑哭了,对此我们有一种新的查找算法:折半查找,具体思想如下图:

FqI92-Nz2bNW1kfx4m2dJqGAo9Qi这就是二分查找的算法思想,它循环一次可以为我们略去一半的无用数据,假如要查找的数就在mid的位置,我们的效率就会大大提高。什么?在第一个顺序查找快?呵呵…杠精必死

二分查找算法的时间复杂度为 O (log2n) ;代码实现也比较容易,我也放在下面了:

1 int binarySearch(int arr[],int len,int num) {

2 int left = 0;

3 int right = len -1; //数组长度-1

4 if(left > right) {

5 printf("ERROR!\n");

6 return 0;

7 }

8 while(left <= right) {

9 int mid = (left + right)/2; //每次循环mid的值都需要重新计算

10 if(arr[mid] == num) {

11 return mid;

12 }

13 if(arr[mid] < num) {

14 left = mid;

15 }else{

16 right = mid;

17 }

18 }

19 }

插值查找(interpolation search)

插值算法其实就是在二分查找算法上做了一些优化,在介绍它之前先思考两个问题

第一,为什么要先去中间找而不是除以4,乘以 3/4,去前面或后面找?

第二,你在翻一本书时,已知它有300页左右,要翻到30页,或者250页,你会先去往中间翻么?

插值查找就是这个意思,我要从更贴近答案的地方开始找,而不是固定往中间开始找。

那问题来了,我们怎么去找这个更贴近的位置呢?嗯…先来看看二分查找吧

在二分查找,我们找中间位置 是让 mid = (left + right)/ 2 = left + 1/2(right - left)

通过类比的思想,我们可以把这里的1/2 类比为 (num - left)/ (arr[right] - arr[left])

也很好理解,想象一把20cm的绳子,我要找5cm长的地方,是不是就要去 (5 - 0) / (20 - 0) = 1/4的地方找,就更靠近 ,两个差不多一个意思

算法 代码 其实也差不多 直接给你们附上:

FkOD4p4PUDIN2bSpZuLlK6Y912QU补充一下:插值算法的算法复杂度是O(log2(log2n)),最坏也会达到O(n),因为数组里面的数值我们不知道,在它跨度很大的情况下,算法时间复杂度就会变高,我们做的只是尽量去贴近我们要查找的值。

代码块:

1 int interpolationSearch(int arr[],int len,int num) {

2 int left = 0;

3 int right = len -1; //数组长度-1

4 if(left > right) {

5 printf("ERROR!\n");

6 return 0;

7 }

8

9 while(left <= right) {

10 int mid = left + (num - arr[left])/(arr[right] - arr[left]) * (right - left);

11 // (num - arr[left])/(arr[right] - arr[left])就是所谓的插值

12 if(arr[mid] == num) {

13 return mid;

14 }

15 if(arr[mid] < num) {

16 left = mid;

17 }else{

18 right = mid;

19 }

20 }

21 }

最后再说一下吧,二分查找和插值查找都属于有序查找,有一定局限性,但好用啊,对吧。然后这两个都可以用函数递归来写,但咱还没学,后面有机会再补充,有错误的地方如果有人看,这很重要,麻烦帮忙指出哈,大家一起学习嘛,自己也就是个渣渣,不谈了不谈了,溜了溜了。后面还有查找算法没讲,后面学了会再写。

@xiaolv

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值