二分查找算法讲解及其C++代码实现

Posted OI博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分查找算法讲解及其C++代码实现相关的知识,希望对你有一定的参考价值。

二分查找算法是一种常用的查找算法,也被称为折半查找。它可以在有序的数组或列表中快速查找需要的元素。

算法描述:

  1. 首先确定数组的中间位置mid=(left+right)/2;
  2. 然后将要查找的值key与中间位置的值进行比较;
  3. 如果key等于中间位置的值,则查找成功,返回mid;
  4. 如果key小于中间位置的值,则在左半部分继续查找;
  5. 如果key大于中间位置的值,则在右半部分继续查找;
  6. 重复以上步骤,直到查找到key或者left>right时,查找结束。

C++代码实现:

int binarySearch(int arr[], int n, int key)

    int left = 0;
    int right = n - 1;
    while (left <= right)
    
        int mid = (left + right) / 2;
        if (arr[mid] == key)
            return mid;
        else if (arr[mid] > key)
            right = mid - 1;
        else if (arr[mid] < key)
            left = mid + 1;
    
    return -1; // 查找失败,返回-1

该函数接收三个参数,分别是:

  1. arr:有序数组指针;
  2. n:数组长度;
  3. key:要查找的值。

如果查找成功,函数将返回该元素在数组中的下标;否则,返回-1表示查找失败。

注意:使用二分查找算法前,必须先对数组进行排序。

二分查找算法的递归循环实现及其缺陷

关于二分查找法

      在学习算法的过程中,我们除了要了解某个算法的基本原理、实现方式,更重要的一个环节是分析算法的复杂度。在时间复杂度和空间复杂度之间,我们又会更注重时间复杂度,往往用牺牲空间换时间的方法提高时间效率。

时间复杂度按优劣排差不多集中在:

O(1), O(log n), O(n), O(n log n), O(n2), O(nk), O(2n)

二分查找法主要是解决在“一堆数中找出指定的数”这类问题,而想要应用二分查找法,这“一堆数”必须有一下特征:

  • 存储在数组中

  • 有序排列

所以如果是用链表存储的,就无法在其上应用二分查找法了。

至于是顺序递增排列还是递减排列,数组中是否存在相同的元素都不要紧。不过一般情况,我们还是希望并假设数组是递增排列,数组中的元素互不相同

二分查找程序实现:

#include<iostream>

using namespace std;


//while循环实现

int Binary_Search1(int array[], int n, int value)

{

int left = 0;

int right = n-1;

while (left <= right)//注意这里是"<="还是"=",若为"=",则循环里改为right = middle 

{

int middle = left + ((right - left) >> 2);//直接平均可能會溢位,所以用此算法

if (array[middle] > value)

{

right = middle - 1;

}

else if(array[middle] < value)

{

left = middle + 1;

}

else

{

return middle;

}

}

return -1;

}



//递归实现

int Binary_Search2(int array[], int left,int right, int value)

{

if (left > right)//二分查找要有序

{

return -1;

}

int middle = left + ((right - left) >> 2);//直接平均可能會溢位,所以用此算法

if (array[middle] > value)

{

return Binary_Search2(array, left, middle - 1, value);

}

else if (array[middle] < value)

{

return Binary_Search2(array, middle + 1, right, value);

}

else

{

return middle;

}

}



int main()

{

int array[10] = { 1,2,3,5,7,8,9,11,13,45 };

int n = 0, num = 0,ret=0;

n = sizeof(array);

/*int left = 0, right = n-1;*/

cin >> num;

ret = Binary_Search1(array, n, num);

/*ret = Binary_Search2(array, left,right, num);*/

if (ret == -1)

{

cout << "查找失败!"<< endl;

}

else

{

cout << num << "是第" << ret + 1 << "个数" << endl;

}

system("pause");

return 0;

}

运行结果1:

8

8是第6个数

请按任意键继续. . .


运行结果2:

17

查找失败!

请按任意键继续. . .


二分查找法的缺陷

二分查找法的O(log n)让它成为十分高效的算法。不过它的缺陷却也是那么明显的。就在它的限定之上:

     必有序,我们很难保证我们的数组都是有序的。当然可以在构建数组的时候进行排序,可是又落到了第二个瓶颈上:它必须是数组数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n)。因而导致构建有序数组变成低效的事情。

       解决这些缺陷问题更好的方法应该是使用二叉查找树了,最好自然是自平衡二叉查找树了,高效的(O(n logn))构建有序元素集合,又能如同二分查找法一样快速(O(log n))的搜寻目标数。


本文出自 “岩枭” 博客,请务必保留此出处http://yaoyaolx.blog.51cto.com/10732111/1775691

以上是关于二分查找算法讲解及其C++代码实现的主要内容,如果未能解决你的问题,请参考以下文章

STL中的二分查找

二分查找算法的递归循环实现及其缺陷

二分查找算法的C++和PHP实现方法

二分查找(折半算法实现)

算法系列二分查找的“变形记”

分治算法-二分查找