【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






目录
相关文章
|
2天前
|
自然语言处理 算法 搜索推荐
C语言中谈论算法
C语言中谈论算法
11 0
C语言中谈论算法
|
2天前
|
算法 安全 C语言
使用C语言实现DES算法代码
使用C语言实现DES算法代码
|
2天前
|
算法 搜索推荐 C语言
C语言的算法
C语言的算法
19 0
|
2天前
|
自然语言处理 算法 搜索推荐
C语言用伪代码表示算法
C语言用伪代码表示算法
41 0
|
2天前
|
算法 C语言 人工智能
|
2天前
|
算法 C语言
C语言易混淆、简单算法、结构体题目练习、常见关键字总结-2
C语言易混淆、简单算法、结构体题目练习、常见关键字总结
|
2天前
|
算法 编译器 API
C语言易混淆、简单算法、结构体题目练习、常见关键字总结-1
C语言易混淆、简单算法、结构体题目练习、常见关键字总结
|
2天前
|
存储 缓存 算法
【C 言专栏】C 语言实现算法的高效性
【5月更文挑战第6天】本文探讨了C语言在实现高效算法上的优势,包括其高效性、灵活性、可移植性和底层访问能力。关键点包括选择合适的数据结构(如数组、链表、树和图)、应用优化策略(如减少计算、空间换时间、分治和动态规划),以及内存管理和代码优化技巧。通过实际案例(如排序和图遍历算法),阐述了如何利用C语言实现算法高效性,并强调在实践中不断探索和优化以提升算法效率。C语言在计算机科学中的重要地位使其成为实现高效算法的首选工具。
【C 言专栏】C 语言实现算法的高效性
|
2天前
|
搜索推荐 C语言
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
11 0
|
2天前
|
算法 搜索推荐 C语言
C语言用流程图表示算法
C语言用流程图表示算法
23 0