二分查找原理
二分查找法为什么会出现?
在一个有序排列的数组中查找想要找的数字n,很容易想到的方法是遍历数组。
如以下代码,便是在一个已知的有序数组中通过循环来查找数据。
#include <stdio.h>
int main()
{
int arr[5] = { 1,2,3,4,5 };
int i = 0;
int flag = 1;
while(flag)
{
if (arr[i] == 5)
{
printf("找到了,下标是%d", i);
flag = 0;
}
else if (arr[i] != 5)
{
i++;
}
}
if(flag=0)
printf("找不到了");
return 0;
}
但是这种方法的效率比较低,因此人们发明了新的方法,即二分查找法。
二分查找法的原理
二分查找法的前提条件是有序数组,原理是每次都取这个数组的中间数据,然后与我们所想要得到的数据进行对比,从而确定一个新的范围,再之后去寻找新的范围的中间值,之后再次进行比较,以此反复循环,直到找到这个数据。
下面讲解具体实施方法,我们首先要定义三个量
left:表示开始查找的起始值。
right:表示查找的末尾值。
mid:表示中间数值,用以判断是否需要下次查找。
有了这三个量,下面我们就来通过下图来体验二分查找的过程。
下面我们循序渐进的来完成二分查找的步骤。
二分查找法的完成
首先,我们应先创建一个有序的数组,如下。
若要我们在这个数组中查找7,我们应该怎么做?
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
return 0;
}
因为我们是通过计算出这个数组的中间数据的下标,然后再进行比较,因此我们需要定义上述的left right mid三个变量。但这里我们便遇到了问题,难道一个100000个数据的数组也需要我们数出来这个数组有多少个么?
因此,我们需要用到sizeof,具体措施如下。
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) - 1;//我们要通过下标去寻找,但我们的下标是从0开始的,所以下标个数要比元素个数少1.
下面我们遇到了新的问题,如何每次都得到mid值? 下面通过图引来让大家了解这个问题。公主王子请看图
因此,我们便得到了可定义的mid值。
int mid = mid = left + (right - left) / 2;
下面我们便可以着手这个问题的完成。
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) - 1;
int mid = mid = left + (right - left) / 2;
int key = 7;
if (arr[mid] > key)
{
right = mid - 1;
}
else
{
left = mid + 1;
}
return 0;
}
我们将我们所想要寻找的数值定义为k,再大抵将我们的框架写出,然后我们便发现,这个东西应该是一个循环,所以我们需要一个while循环。
现在我们便真正完成了我们的框架,但是我们发现,若我们查找到了我们想要的数据之后,该循环还会继续进行,并不会跳出,因此我们需要使用break跳出该循环。
下面我们就要开始考虑一个问题,若我们要查找的数据不在该数据中该怎么办?这时就需要我们进行一次判断。因此我们需要定义一个新的变量flag用于判断。若flag=1,则打印出所需要找的数据的下标;若flag=0,则代表我们要找的数据不在这个数组中。因此,我们便完成了这次二分查找。
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) - 1;//我们要通过下标去寻找,但我们的下标是从0开始的,所以下标个数要比元素个数少1.
int mid = 0;
int key = 7;
int flag = 0;
while (left <= right)//当left大于right,则寄!
{
mid = left + (right - left) / 2;
if (arr[mid] > key)
{
right = mid - 1;
}
else if (arr[mid] < key)
{
left = mid + 1;
}
else
{
flag = 1;
break;
}
}
if (1 == flag)
printf("找到了,下标是%d\n", mid);
else
printf("找不到\n");
return 0;
}
现在我们便完成了二分查找的讲解,但,若我们定义k=17会出现什么现象呢?劳烦大家自行尝试!