二分查找(图解与完整代码实现)

原理:

二分法:二分查找算法是在有序数组中查找某一特定元素的搜索算法,思想为,不断将有序查找表“一分为二”,减少搜索区域,以至找到目标元素

  1. 搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;
  2. 如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。
  3. 如果在某一步骤数组 为空,则代表找不到。
  4. 这种搜索算法每一次比较都使搜索范围缩小一半。折半搜索每次把搜索区域减少一半,时间复杂度为Ο(logn)

前提!!!:数组有序

二分查找图解:以有序数组{4, 9,12,23,30,76, 88,99}为,需要查找30.


初始状态

第一轮:23<30,判定在30在23的右边区域,更新搜索区域。

二分查找(图解与完整代码实现)_第1张图片
第二轮:搜素位置中心为76,更新搜索区域在76左侧。

第三轮:low==high,不再进入循环体,

(low+high)/2 == mid,因此中间元素就是30,该元素就是要找的目标元素。

代码实现:

(while循环)

#include

//二分查找函数

int binarySearch(int arr[], int n, int x) {

    int left = 0;//左边界

    int right = n-1;//右边界

    while (left <= right) { //左边界小于等于右边界循环

         int mid = left + (right - left) / 2;//中间位置

         if (arr[mid] == x) {//中间位置等于目标元素,返回

             return mid;

         }

         else if (arr[mid] < x) {//中间位置小于目标元素,更新左边界,再次查找

             left = mid+1;

         }

         else

         {

             right = mid - 1;//否则更新右边界,再次查找

         }

    }

    return -1;

}

int main() {

    int arr[] = { 1,3,4,5,7,9 };

    int n = sizeof(arr) / sizeof(arr[0]);//数组长度

    int x ;

    scanf("%d", &x);

    int result = binarySearch(arr, n, x);

         if (result == -1) {

             printf("没有找到该元素");

         }

         else

         {

             printf("下标为%d", result);

         }

        

         return 0;

}

(递归)

//递归

#include

int binarySearch_Recursive(int arr[], int left, int right, int x) {

    if (left <= right) {

         int mid = left + (right - left) / 2;

         if (arr[mid] == x) {

             return mid;

         }

         else if (arr[mid]<x)

         {

             return binarySearch_Recursive(arr,mid+1,right,x);

         }

         else

         {

             return binarySearch_Recursive(arr, left, mid - 1, x);

         }

    }

    return -1;

}

int main() {

    int arr[] = { 1,3,4,5,7,9 };

    int n = sizeof(arr) / sizeof(arr[0]);//数组长度

    int x;

    scanf("%d", &x);

    int result = binarySearch_Recursive(arr, 0,n-1, x);

    if (result == -1) {

         printf("没有找到该元素");

    }

    else

    {

         printf("下标为%d", result);

    }

    return 0;

}

代码效果:

注意:递归查找,每次递归,需要缩小范围,每次左右边界的值都在改变,所以需要将左右边界传入,定义为binarySearch_Recursive(int arr[], int left, int right, int x)将之与while循环的binarySearch(int arr[], int n, int x) 区分开

二分查找的优缺点:

优点:

  1. 高效,时间复杂度O(logn)。
  2. 在已经排序好的静态数组和链表中,二分查找性能强大,能够快速定位

缺点:

  1. 前提条件待查找序列必须有序,如未有序,需要先排序,增加时间和空间复杂度
  2. 数组大小固定,不能调整,数据大的情况下,占空间大
  3. 只能进行单个元素的查找
  4. 序列中有重复元素,查找结果可能不唯一,需要进一步处理

你可能感兴趣的:(算法,c语言)