二分查找(折半查找)

目录

一般情况

1.首先我们先要定义一个有序数组

2.假设我们要找数字7

3.因为要用下标确定数组里面的元素,所以我们写一个循环把数组里面所有元素罗列出来

4.然后判断数组里面的每个元素符不符合要求

5.还有另外一种可能,就是当全部判断完之后,发现没有符合要求的元素,这时候我们就需要修改代码,当break跳出的时候,会来到return 0;的前面,这时我们定义一个变量flag,来表示他没有找到。

二分查找逻辑

二分查找代码

1.首先定义数组,左下标,右下标

2.算出中间下标

3.判断

4.上述代码中之执行了一次,要让他多次判断,我们就需要利用while循环

5.我们加入flag判断找到了没有

6.添加循环条件

运行结果:


在一个有序数组中查找具体的某个数字n

一般情况

1.首先我们先要定义一个有序数组

#include<stdio.h>
int main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    return 0;
}

2.假设我们要找数字7

#include<stdio.h>
int main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int k=7;    //查找7
    return 0;
}

3.因为要用下标确定数组里面的元素,所以我们写一个循环把数组里面所有元素罗列出来

#include<stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 7;    //查找7
    int i = 0;
    for (i = 0; i < 10; i++)
    {

    }
    return 0;
}

4.然后判断数组里面的每个元素符不符合要求

#include<stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 7;    //查找7
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        if (arr[i] == k)
        {
            printf("找到了,元素的下表是%d\n",i);
            break;
        }
    }
    return 0;
}

5.还有另外一种可能,就是当全部判断完之后,发现没有符合要求的元素,这时候我们就需要修改代码,当break跳出的时候,会来到return 0;的前面,这时我们定义一个变量flag,来表示他没有找到。

#include<stdio.h>
int main()
{
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int k = 7;    //查找7
    int i = 0;
    int flag = 0;
    for (i = 0; i < 10; i++)
    {
        if (arr[i] == k)
        {
            printf("找到了,元素的下表是%d\n",i);
            flag = 1;
            break;
        }
    }
    //break,找不到的时候也会来到这里
    if (flag == 0)
        printf("找不到\n");
    return 0;
}

到这里我们的一般情况就写完了,这种方式有一个弊端,就是当这个有序数组规模非常大时,他的执行效率太低了,当一个有序数组有n个元素时,最坏的情况下我们要找n次,假设有一万个有序数字,他最多要查找一万下,这时就有了一种效率更高的方法,那就是二分查找。


二分查找逻辑

首先我们要理解二分查找的逻辑,假设我买了一双鞋子550元,我叫你来猜这双鞋的价格,你说给个范围我猜,我就说1—1000元之间,为了更快的猜对价格,你肯定会猜1—1000最中间的价格,比如你说500元,我对你说猜小了,然后你又说600元,我会你说猜大了,然后你说550元,我就会和你说猜对了,肯定没有人从1元开始,然后一一往上加,这就是二分查找的逻辑。

假设这个数组里面有1,2,3,4,5,6,7,8,9,10这十个数字

我们还是要找k,k里面放的是7

我们先要找这个数组里面的中间元素

我们就利用数组的下标访问元素

我们把最左边的下标定义成left

我们把最右边的下标定义成right

我们把中间元素的下标定义成mid

 当我们用这种方式找到中间元素的下标时,发现并没有成功找到k,而是比它小,所以我们的查找范围就缩小到下标为5,6,7,8,9的元素

也就是有序数组里面卖的6,7,8,9,10。

这时候我们就需要进行第二次查找。

 

 当我们用这种方式进行第二次查找时,发现并没有成功找到k,而是比它大,所以我们的查找范围就缩小到了下标为5,6的元素

也就是有序数组里面的6,7。

这个时候我们就绪需要进行第三查找。

当我们用这种方式进行第三次查找时,发现并没有成功找到k,而是比它小,所以我们的查找范围就缩小到了6

也就是有序数组里面的7

这个时候我们就绪需要进行最后一次查找。

 当我们查找到第四次的时候,我们就找到了下标为6的元素,也就是7

k=7

这个时候我们就找到了

我们用这种方式每查找一次就能砍掉一半的数据,这种方式被称为折半查找,也被称为二分查找

逻辑明白了,接下来我们就用代码把他写出来

二分查找代码

1.首先定义数组,左下标,右下标

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;    //查找7
	int left = 0;    //左下标
	int right = 9;    //右下标
	return 0;
}

2.算出中间下标

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int left = 0;
	int right = 9;

	int mid = (left + right) / 2;//中间元素的下标
	return 0;
}

3.判断

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int left = 0;
	int right = 9;

	int mid = (left + right) / 2;//中间元素的下标
	if (arr[mid] > k)
	{
		right = mid - 1;
	}
	else if (arr[mid] < k)
	{
		left = mid + 1;
	}
	else
	{
		printf("找到了,下标是%d\n",mid);
	}
	return 0;
}

4.上述代码中之执行了一次,要让他多次判断,我们就需要利用while循环

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int left = 0;
	int right = 9;

	while ()
	{
		int mid = (left + right) / 2;//中间元素的下标
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
				left = mid + 1;
		}
		else
		{
			printf("找到了,下标是%d\n",mid);
		}
	}
	
	return 0;
}

5.我们加入flag判断找到了没有

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int left = 0;
	int right = 9;
	int flag = 0;

	while ()
	{
		int mid = (left + right) / 2;//中间元素的下标
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
				left = mid + 1;
		}
		else
		{
			printf("找到了,下标是%d\n",mid);
			flag = 1;
			break;
		}
	}
	if (flag = 0)
	{
		printf("找不到");
	}
	return 0;
}

6.添加循环条件

left<=right的时候,表示他们之间还有元素,当left>right的时候,就表示他们之间没有元素可以找了。

所以条件就是left<=right

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int k = 7;
	int left = 0;
	int right = 9;
	int flag = 0;

	while (left <= right)
	{
		int mid = (left + right) / 2;//中间元素的下标
		if (arr[mid] > k)
		{
			right = mid - 1;
		}
		else if (arr[mid] < k)
		{
				left = mid + 1;
		}
		else
		{
			printf("找到了,下标是%d\n",mid);
			flag = 1;
			break;
		}
	}
	if (flag = 0)
	{
		printf("找不到");
	}
	return 0;
}

运行结果:

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值