今天看了看二分查找的算法,有不少心得理解,有误希望指正。(内容比较基础详细,请放心使用)


正文开始

首先对于二分查找,本质是对查找有序数组遍历算法的优化(什么是查找有序数组的遍历呢,就是把数组全部走一遍,找到想要的数就跳出来),而二分查找就不一样,找中间值比较从数组两边向中间逼近去找到那个数。

文字描述可能有点不好理解,上代码。

#include <stdio.h>
#include <stdlib.h>
//自己想法,对于二分查找法,关键在于边界的控制
//设置right,lift为两个边界下标
int main()
{
int k;//
int arr[]={1,2,3,4,5,6,7,8,9,10};//定义数组
int top = sizeof(arr)/sizeof(arr[0]);//计算数组长度
int left=0;//左下标
int w;//中间值
int right=top-1;//右下标
scanf("%d",&k);//所寻找数字
while(1)//无限循环通过判断去跳出
{
w=(left+right)/2;
if(arr[w]==k)//找到数,退出
{
printf("数值下标为%d",w);//输出数值下标
break;
}
if(right==left)//左右下标重叠,退出循环
{
printf("没有这个数");
break;
}
if(arr[w] >k)
right=w-1;//从右向左逼近
else
left=w+1;//从左向右逼近
}
system("pause");
return 0;
}

这就结束了?心得理解就这?

当然不是,接下来才是重点。###

#1仔细看代码会发现


    if(arr[w] >k)
right=w-1;//从右向左逼近
else
left=w+1;//从左向右逼近

为什么有-1,+1呢?对-1来说吧

因为比较的是arr[w],既然已经比较了下标为w的这一个数字。说明arr[w]已经比k大了,那么k肯定在arr[w]左边,当然可能没有这个值,所以说右边界要在arr[w-1]处。

#2在while中有三个东西

首先是判断找到,再是判断重叠,最后是逼近中间值。这三块代码可以换位置吗?

对于判断找到和判断重叠我觉得是不能的,一定是判断找到在前,判断重叠在后。

为什么呢?因为假设是找7这个数



left(存储下标)

实际值

right(存储下标)

实际值

w

arr[w]

初始

0

1

9

10

w=(0+9)/2=4

5

第一次

4+1=5

6

9

10

w=(5+9)/2=7

8

第二次

5

6

6

7

w=(5+6)/2=5

6

第三次

5+1=6

7

6

7



可以看到,当在这个数组中寻找7的时候,最终right和left相等了,为6。而刚好arr[6]=7;

如果先判断重叠再判断找到的话就会直接跳出循环。

#3为什么要用到算法优化呢,假如说是一组特别大的数据,遍历可能跑很久很久,是一种很浪费资源的行为,所以说有了二分查找算法。遍历是O(n)的算法而二分查找法是O(log2n),第三条看不懂没关系,这是复杂度的问题,在之后的学习会碰到的。