二分法详解

时间复杂度

 

二分查找的最优时间复杂度为 O(1)。

二分查找的平均时间复杂度和最坏时间复杂度均为O(logn) 。因为在二分搜索过程中,算法每次都把查询的区间减半,所以对于一个长度为n 的数组,至多会进行O(logn) 次查找。

空间复杂度

迭代版本的二分查找的空间复杂度为 O(1)。

递归(无尾调用消除)版本的二分查找的空间复杂度为O(logn).

代码

int binary_search(int start, int end, int key) {
  int ret = -1;  // 未搜索到数据返回-1下标
  int mid;
  while (start <= end) {
    mid = start + ((end - start) >> 1);  // 直接平均可能会溢出,所以用这个算法
    if (arr[mid] < key)
      start = mid + 1;
    else if (arr[mid] > key)
      end = mid - 1;
    else {  // 最后检测相等是因为多数搜索情况不是大于就是小于
      ret = mid;
      break;
    }
  }
  return ret;  // 单一出口
}

qsort bsearch

qsort 函数有四个参数:数组名、元素个数、元素大小、比较规则。其中,比较规则通过指定比较函数来实现,指定不同的比较函数可以实现不同的排序规则。

比较函数的参数限定为两个 const void 类型的指针。返回值规定为正数、负数和 0。

比较函数的一种示例写法为:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
int compare(const void *p1, const void *p2)  // int 类型数组的比较函数
{
  int *a = (int *)p1;
  int *b = (int *)p2;
  if (*a > *b)
    return 1;  // 返回正数表示 a 大于 b
  else if (*a < *b)
    return -1;  // 返回负数表示 a 小于 b
  else
    return 0;  // 返回 0 表示 a 与 b 等价
}

注意:返回值用两个元素相减代替正负数是一种典型的错误写法,因为这样可能会导致溢出错误。

cmp

bool cmp(int a,int b){
    return a>b;//降序  
}

bsearch--lower_bound

int A[100005];  // 示例全局数组

// 查找首个不小于待查元素的元素的地址
int lower(const void *p1, const void *p2) {
  int *a = (int *)p1;
  int *b = (int *)p2;
  if ((b == A || compare(a, b - 1) > 0) && compare(a, b) > 0)
    return 1;
  else if (b != A && compare(a, b - 1) <= 0)
    return -1;  // 用到地址的减法,因此必须指定元素类型
  else
    return 0;
}

 C++ 中的 lower_bound 和 upper_bound 函数

lower_bound()返回值是一个迭代器,返回指向大于等于key的第一个值的位置

对象:有序数组或容器

数组:

#include <algorithm>
#include <iostream>
using namespace std;
int main()
{
    int a[]={1,2,3,4,5,7,8,9};

printf("%d",lower_bound(a,a+8,6)-a);

return 0;

}

输出:5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值