【C语言】带你玩转经典算法用二分法在一个有序数组中查找某个数

简介: 【C语言】带你玩转经典算法用二分法在一个有序数组中查找某个数

前言

二分法在C语言初阶中是一种非常经典的算法,今天就来带大家认识一下它。

一.经典法

利用循环与判断语句通过遍历的方式实现

  • 代码如下:
int main()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//升序
  int k = 7;
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    if (arr[i] == k)
    {
      printf("找到了,下标是:%d\n", i);
      break;
    }
  }
  if (i == 10)
  {
    printf("找不到\n");
  }
  return 0;
}

这样雀氏能达到我们的目的,但是转念想想,是不是有点太大材小用了?

如果这个数组并不是一个有序数组,我们依然能用这种方法达到我们的目的

但是于此同时,由于我们每个数都要判断一遍,这大大增加了我们的时间复杂度。

有没有更加简单且时间复杂度更低的算法呢?

当然有,下面我们来介绍一下通过二分法实现在有序数组中的查找。

二.分法查找

1.什么是二分法?

首先对于一个有序数组,它一定是满足升序或者降序的(即前一个数的值一定比后一个数小(大))。

而我们的二分法查找,它只适用于在有序数组里查找某个数

画图解释一下

1e7a2731dd4e409c8ff9cfc99d3d64dc.png

了解了二分法的基本原理,我们来具体实现一下

2.二分法的使用

还是通过代码来讲解一下

int main()
{
  int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//升序
  int k = 7;
  int i = 0;
  int sz = sizeof(arr) / sizeof(arr[0]);//利用数组的总大小除以数组中一个元素的大小,得到数组中一共存放了几个元素
  //1
  int left = 0;
  int right = sz-1;//数组下标是数组元素个数-1
  int flag = 0;//flag的作用是标志是否找到了
  //2
  while (left<=right)//当左右都指向同一个数时还没找到,说明此数不存在
  {
    int mid = (left + right) / 2;
    if (arr[mid] == k)
    {
      printf("找到了,下标是:%d\n", mid);
      flag = 1;//令flag等于1
      break;
    }
    else if (arr[mid] < k)//mid就比k小,舍去比mid更小的数
    {
      left = mid + 1;
    }
    else//mid比k大,舍去比mid大的数
    {
      right = mid - 1;
    }
  }
  //1 2
  if (flag == 0)//判断是否找到k,如果找到,flag应等于1
    printf("没找到\n");
  return 0;
}

运行结果如下

d1a6c612d502450dbc3eb2ca8ea89763.png

为了防止某些初学者还是没弄懂,我们这里也画个图说明一下。

注意:由于left right mid均是整型,当出现小数是会自动把小数给舍去

假设此时的k=7

在上面的代码的注释中,我解释了中间值mid的由来。这里不再缀叙。

12c02745b0b4457286913cc733593a28.png

-此时锁定的k的范围为

280aa7b8f0bc4d1e8995ce5dfd7bb610.png

第二次比较后,mid反而比k大了,那么就要舍去比mid还大的数。此时k的范围:

b52ebe8634054624ab10bc78c1df3fd4.png

此时mid与left指向了同一位置,但是mid此时仍然小于k,Left=mid+1,当出现这种情况时,Left,Right,mid均指向数组下标为6的元素,如果此时还找不到k,说明这个数组中就没有看,但在图中这种情况,此时mid值与k相等,我们找到了我们想要的k,下标是mid。

10dae67526264b3995c80e194f0d3088.png

3.二分法的优点与缺陷

通过上面两种方法的对比我们可以很明显的看出来,二分法的时间复杂度要远远小于经典法,比如咱们要从一个四位数中找某个数,经典法可能要运行个几千次才能找到,而对于二分法来说,可能十次不到就解决了

但是万事都是有利必有弊的,对于二分法来说,它的使用条件仅限于在一系列有序数中查找某个数,一旦在这个数组是无序的,那么二分法就无法满足我们查找的要求,而经典法通过遍历就能实现我们的要求。

总结

二分法虽好但有严苛的使用条件,在我们实际应用的过程中,一定要结合实际要求来选择是使用二分法还是经典法,万万不可不分情况随意使用。


好了,以上就是今天的主要内容了,如果你有什么疑问欢迎在评论区提出或者私信我哦,博主看到会第一时间回复滴!


如果觉得今天的内容对你有用的话,不妨点个三连再走啊,感谢大家的支持,你们的支持就是我更新的动力!!!

3f3dcaf156eb427e8fb4f8c272ae8a18.jpg






目录
相关文章
|
5月前
|
C语言
【C语言刷题系列】合并两个有序数组
【C语言刷题系列】合并两个有序数组
|
3月前
|
存储 算法 C语言
"揭秘C语言中的王者之树——红黑树:一场数据结构与算法的华丽舞蹈,让你的程序效率飙升,直击性能巅峰!"
【8月更文挑战第20天】红黑树是自平衡二叉查找树,通过旋转和重着色保持平衡,确保高效执行插入、删除和查找操作,时间复杂度为O(log n)。本文介绍红黑树的基本属性、存储结构及其C语言实现。红黑树遵循五项基本规则以保持平衡状态。在C语言中,节点包含数据、颜色、父节点和子节点指针。文章提供了一个示例代码框架,用于创建节点、插入节点并执行必要的修复操作以维护红黑树的特性。
101 1
|
19天前
|
存储 算法 数据管理
C语言算法复杂度
【10月更文挑战第20天】
C语言算法复杂度
|
1月前
|
存储 算法 C语言
【C语言】二分查找算法
【C语言】二分查找算法
|
1月前
|
算法
❤️算法笔记❤️-(每日一刷-26、删除有序数组的重复项)
❤️算法笔记❤️-(每日一刷-26、删除有序数组的重复项)
23 0
|
1月前
|
搜索推荐 C语言 C++
【C语言】指针篇-精通库中的快速排序算法:巧妙掌握技巧(4/5)
【C语言】指针篇-精通库中的快速排序算法:巧妙掌握技巧(4/5)
|
3月前
|
机器学习/深度学习 存储 并行计算
C语言与机器学习:K-近邻算法实现
C语言与机器学习:K-近邻算法实现
61 0
|
3月前
|
算法 Java
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
LeetCode初级算法题:环形链表+排列硬币+合并两个有序数组java解法
54 0
|
5月前
|
算法 C语言
C语言----判断n是否是2的次方数,利用到按位与&,算法n&(n-1)
C语言----判断n是否是2的次方数,利用到按位与&,算法n&(n-1)
|
5月前
|
存储 算法 Java
Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。
【6月更文挑战第21天】Java查找算法概览:二分查找适用于有序数组,通过比较中间元素缩小搜索范围;哈希查找利用哈希函数快速定位,示例中使用HashMap存储键值对,支持多值关联。简单哈希表实现未涵盖冲突解决和删除操作。
59 1