二分查找实现

二分查找(折半查找)

时间复杂度:O(logN), 以2为底
前提:单调序列,编写代码需已知单增或单减
终止条件: head > tail
循坏条件: head <= tail
待查找元素:x,仅仅是找到数x是否存在该数组中,返回下标值, 如果数组中出现相同元素,二分查找是随机找到一个即可,返回下标。
描述:head指向头部,tail指向尾部,每次劈一半(扔掉)
标准版二分查找
#include <stdio.h>

# 实现在一个数组arr中查找元素x是否存在,数组长度为len,若找到x,返回x数组下标,否则返回-1
int binary_search(int *arr, int len, int x) {
    int head = 0, tail = len - 1, mid;
    while (head <= tail) {
        mid = (head + tail) >> 1;
	if (arr[mid] == x) return mid;
	if (arr[mid] < x) head = mid + 1;  // 假设单调递增
	else tail = mid - 1;
    }
    return -1;
}


int main() {
    #define MAX_N 100
    int num[MAX_N + 5], n, x;
    scanf("%d", &n);  // 数组长度n
    for (int i = 0; i < n; i++) {
      scanf("%d\n", (num + i));
    }    // 键入n个数据
    while (~scanf("%d", &x)) {
        printf("%d\n", binary_search(num, n, x));
    }    // 循坏读入,待判断的x
    #undef MAX_N
    return 0;
}
7                 // 数据长度n
1 3 5 7 9 10 12   // 数组的n个元素
1                 // 待判断查找的x
0                 // 返回的下标
3
1
10
5
13
-1
递归版二分查找
#include <stdio.h>

// 递归版二分法
int binary_search(int *arr, int head, int tail, int x) {
    if (head > tail) return -1;
    int mid = (head + tail) >> 1;
    if (arr[mid] == x) return mid;
    if (arr[mid] < x) head = mid + 1;
    else tail = mid - 1;
    return binary_search(arr, head, tail, x);
}


int main() {
    #define MAX_N 100
    int num[MAX_N + 5], n, x;
    scanf("%d", &n); 
    for (int i = 0; i < n; i++) {
      scanf("%d\n", (num + i));
    }    
    while (~scanf("%d", &x)) {
        printf("%d\n", binary_search(num, 0, n - 1, x));
    }
    #undef MAX_N
    return 0;
}

arr( ) 函数 y = f ( x ) , x 与 y 一一对应,映射关系。
arr[ ] 数组 arr[4] = 2 , 数组的下标索引与值也一一对应。
函数是压缩的数组,数组是展开的函数。

用二分法查找设计开平方根

#include <stdio.h>
#include <math.h>

double func(double n) {
    return n * n;
}

double binary_search(double (*arr)(double), double x) {
    double head = 0, tail = x, mid;
    if (x < 1) tail = 1.0;
    #define EE 1e-7
    while (head < tail) {
	    mid = (head + tail) / 2.0;
	    if (fabs(arr(mid) - x) < EE) return mid;
        if (arr(mid) < x) head = mid;
        else tail = mid;	
    }
    #undef EE
    return -1;
}

int main() {
    double x;
    while (~scanf("%lf", &x)) {
        printf("my_sqrt(%g) = %g\n", x, binary_search(func, x));
	    printf("sqrt(%g) = %g\n", x, sqrt(x));
    }
    return 0;
}

>>10
>my_sqrt(10) = 3.16228
>sqrt(10) = 3.16228
>>1
>my_sqrt(1) = 1
>sqrt(1) = 1
>>4
>my_sqrt(4) = 2
>sqrt(4) = 2
>>0.1
>my_sqrt(0.1) = 0.316228
>sqrt(0.1) = 0.316228

二分法习题:方程x*e^x = a,输入a;输出一个浮点数,表示方程的解,四舍五入到小数点后四位

样例
0
>> 0.0000
1
>>0.5671
100
>3.3856
二分法习题
// x * e^x = a
#include <stdio.h>
#include <math.h>

double func(double x) {
    return x * exp(x);
}

double binary_search(double (*arr)(double), int a) {
     double head = 0, tail = a, mid;
     #define EE 1e-7
     while (fabs(head - tail) > EE) {
	     mid = (head + tail) / 2.0;
	     if (fabs(arr[mid] - a) < EE) return mid;
	     if (arr(mid) < a) head = mid;
	     else tail = mid;
     }
     #undef EE
     return head;
    
}
int main() {
    double a;
    while (~scanf("%d", &a)) {
        printf("%.4lf\n", binary_search(func, a));
    }
    return 0;
}

二分查找特殊情况: 1 1 1 1 0 0 0 0 0 0 找出最后一个满足要求的数的位置

#include <stdio.h>

int binary_search(int *arr, int n) {
    int head = -1, tail = n - 1, mid;
    while (head < tail) {
        mid = (head + tail + 1) >> 1;
        if (arr[mid] == 0) tail = mid - 1;
        else head = mid;
    }
    rerurn head;
}

int main() {
    int arr[10] = {1, 1, 1, 1, 0, 0, 0, 0, 0, 0};
    printf("%d\n", binary_search(arr, 10));
    return 0;
}

报数题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值