• 二分查找的递归和非递归写法


    一、概述

    二分查找是针对有序数列的,对无序数列是无效的,在有序序列中使用二分查找能大大提高查找效率,通常能将时间按复杂度从O(n)降至O(logn)。

    二、查找某数的位置(或存在性)

    递归:

     1 //返回"-1"表示为找到
     2 //否则返回目标的下标(若有多个,只是其中一个)
     3 int binary_searchs(int *arr, int target, int l, int r)
     4 {
     5     if (l > r)  return -1;            
     6     int mid = (l + r) >> 1;
     7     if (arr[mid] == target) 
     8         return mid;
     9     else if (arr[mid] > target)
    10         binary_search(arr, target, l, mid - 1);
    11     else 
    12         binary_search(arr, target, mid + 1, r);
    13 }

    非递归:

     1 //返回"-1"表示为找到
     2 //否则返回目标的下标(若有多个,只是其中一个)
     3 int binary_searchs(int * arr, int x, int l, int r)
     4 {
     5     int lt = l, rt = r;
     6     while (lt <= rt)
     7     {
     8         int mid = (lt + rt) >> 1;
     9         if (arr[mid] == x)  return mid;
    10         else if (arr[mid] < x)
    11             lt = mid + 1;
    12         else
    13             rt = mid - 1;
    14     }
    15     return -1;
    16 }

    三、查找某数出现的次数

    递归:

     1 //返回target的出现次数
     2 //返回0意味着不存在
     3 int binary_search(int *arr, int target, int l, int r)
     4 {
     5     if (l > r)  return 0;
     6     int mid = (l + r) >> 1;
     7     if (arr[mid] == target)
     8         return 1 + binary_search(arr, target, l, mid - 1) + binary_search(arr, target, mid + 1, r);
     9     else if (arr[mid] > target)
    10         binary_search(arr, target, l, mid - 1);
    11     else
    12         binary_search(arr, target, mid + 1, r);
    13 }

    递归(优化版):如果有序数列中,目标元素占大多数,二分法会退化成逐一遍历,O(logn)增至O(n),我们要预防这种情况,所以当找到目标元素时,尽可能向两边去找目标元素。

     1 //返回target的出现次数
     2 //返回0意味着不存在
     3 int binary_search(int *arr, int target, int l, int r)
     4 {
     5     if (l > r)  return 0;
     6     int mid = (l + r) >> 1;
     7     if (arr[mid] == target)
     8     {
     9         int cnt1, cnt2;
    10         cnt1 = cnt2 = mid;
    11         if (((cnt1 - 1) >= l) && (arr[cnt1] == arr[cnt1 - 1]))  cnt1--;
    12         if (((cnt2 + 1) <= r) && (arr[cnt2] == arr[cnt2 + 1]))  cnt2++;
    13         return 1 + (cnt2 -cnt1) + binary_search(arr, target, l, cnt1 - 1) + binary_search(arr, target, cnt2 + 1, r);
    14     }
    15     else if (arr[mid] > target)
    16         binary_search(arr, target, l, mid - 1);
    17     else
    18         binary_search(arr, target, mid + 1, r);
    19 }

    非递归:我觉得这个非递归不好写,主要是找到目标元素时,在前一部分和后一部分也有可能存在目标元素,不用递归的方式不好写。以后写出来了再来补吧。

    非递归被同学写出来了,在此补上

     1 int binary_searchs(int *arr, int target,int l, int r)
     2 {
     3     int res = 0;
     4     while (l <= r)
     5     {
     6         int mid = (l + r) >> 1;
     7         if (arr[mid] == target)
     8         {
     9             if (l == r)
    10             {
    11                 res++;
    12                 break;
    13             }
    14             for (int i = mid + 1; i <= r; i++)
    15                 if (arr[mid] == arr[i])
    16                     res++;
    17             for (int i = mid - 1; i >= l; i--)
    18                 if (arr[mid] == arr[i])
    19                     res++;
    20             res++;
    21             break;
    22         }
    23         else if (arr[mid] < target)
    24             l = mid + 1;
    25         else if (arr[mid] > target)
    26             r = mid - 1;
    27     }
    28     return res;
    29 }
  • 相关阅读:
    《信息安全专业导论》第十一周学习总结
    模拟进程
    GPG实践
    信安导论2020-2021上第十三周总结(20201222)
    NMap
    信安导论2020-2021上第十二周总结(20201222)
    python模拟进程状态
    信安导论2020-2021上第十一周总结(20201222)
    信安导论2020-2021上第十周总结(20201222)
    Openssl 20201332
  • 原文地址:https://www.cnblogs.com/lfri/p/9326255.html
Copyright © 2020-2023  润新知