学习心得:二分查找

二分查找

基础:查找元素是否出现

c 复制代码
#include <stdio.h>
int main() {
    int a[10]={0,1,1,3,4,5,6,7,8,9},int x;
    scanf("%d",&x);
    int l=0,r=9,count=0;
    while(l<=r){
        int m=(l+r)/2;
        if(a[m]==x){
            count=m;
            break;
        }
        if(a[m]>x){
            r=m-1;
        }
        if(a[m]<x)
            l=m+1;
    }
    printf("%d",count);
    return 0;
}

高级:查找元素出现次数

当你需要找到目标元素的第一个和最后一个出现位置时,你可以通过稍作修改来实现。以下是一个引导你思路的步骤:

  1. 找到第一个出现位置:
    • 使用标准的二分查找算法找到目标元素。
    • 如果找到目标元素,检查它的前一个元素是否也是目标元素,如果是,则继续在左侧搜索,否则,当前位置就是第一个出现位置。
  2. 找到最后一个出现位置:
    • 同样使用标准的二分查找算法找到目标元素。
    • 如果找到目标元素,检查它的后一个元素是否也是目标元素,如果是,则继续在右侧搜索,否则,当前位置就是最后一个出现位置。
  3. 处理未找到的情况:
    • 如果在第一步找到第一个出现位置时未找到目标元素,或者在第二步找到最后一个出现位置时未找到目标元素,表示目标元素不存在。
c 复制代码
#include<stdio.h>
#include<stdlib.h>
void swap(int *m,int *n){
    int temp=*m;
    *m=*n;
    *n=temp;
}
void sort(int n,int a[n],int l,int r){
    if(l<r) return;
    int key=a[0],ll=l,rr=r;
    while(ll!=rr){
        while(key<=a[rr]&&ll<rr) rr--;
        while(key>=a[ll]&&ll<rr) ll++;
        swap(&a[ll],&a[rr]);
    }
    swap(&a[l],&a[ll]);
    sort(n,a,l,ll-1);
    sort(n,a,ll+1,r);
}
int search(int n,int a[n],int key){
    int l=0,r=n-1;
    while(l<=r){
        int m=(l+r)/2;
        if(a[m]==key){
            int rec1=m,rec2=m;
            while(rec1!=0&&a[rec1-1]==key){
                rec1--;
            }
            while(rec2!=n-1&&a[rec2+1]==key){
                rec2++;
            }
            return rec2-rec1+1;
        }
        if(a[m]<key){
            l=m+1;
        }
        if(a[m]>key) {
            r=m-1;
        }
    }
    return -1;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    int *a=(int *)calloc(n,sizeof(int));
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    int l=0,r=n-1;
    sort(n,a,l,r);
    while(m--){
        int x;
        scanf("%d",&x);
        int count=search(n,a,x);
        if(count==-1){
            printf("0");
        }else{
            printf("%d\n",count);
        }
    }
    free(a);
    return 0;
}

bsearch函数(<stdlib.h>)

bsearch常与qsort函数联合使用。bsearch查找成功返回指向该元素的指针。

4个参数:

key 指向要查找的元素

base 指向进行查找的数组

num 数组中元素的个数

size 数组中每个元素的大小,一般用*sizeof()*表示

cmp 比较两个元素的函数,定义比较规则。需要注意的是,查找数组必须是经过预先排序的,而排序的规则要和比较子函数cmp的规则相同。

  1. 整型
c 复制代码
int cmp(const void *a, const void *b){
	return *(int *)a - *(int *)b;//升序
//	return *(int *)b - *(int *)a;//降序
}
  1. 浮点型

需要注意浮点数会存在精度损失的问题,所以我们需要通过比较,来返回1或-1,以确定是增序还是降序。

c 复制代码
int cmp(const void *a, const void *b){
	return ((*(double *)a - *(double *)b)>0?1:-1);//升序
//	return ((*(double *)a - *(double *)b)<0?1:-1);//降序
}
  1. 字符型
c 复制代码
int cmp(const void *a, const void *b){
	return *(char *)a - *(char *)b;//升序
//	return *(char *)b - *(char *)a;//降序
}
  1. 字符串型
c 复制代码
   int cmp(const void *a, const void *b){
   	return strcmp((char *)a, (char *)b);//升序
   //	return strcmp((char *)b, (char *)a);//降序
   }
  1. 字符串指针数组
c 复制代码
int cmp(const void *a, const void *b){
	return strcmp(*(char **)a, *(char **)b);//升序
//	return strcmp(*(char **)b, *(char **)a);//降序
}
  1. 结构体
c 复制代码
//sample 1
struct node{
	int id;
}s[100]; 
int cmp(const void *a, const void *b){
	struct node *aa = (node *)a;
	struct node *bb = (node *)b;
	return ((aa->id)>(bb->id))?1:-1;//升序
//	return ((aa->id)>(bb->id))?-1:1;//降序
}
//sample 2
struct node{
	int id;
	char data;
}s[100]; 

int cmp(const void *a, const void *b){
	struct node *aa = (node *)a;
	struct node *bb = (node *)b;
	if(aa->id == bb->id)//若id相同,按照data排序 
		return aa->data - bb->data;
	else//否则按照id排序 
		return aa->id - bb->id;//升序
}
相关推荐
霁月风29 分钟前
设计模式——适配器模式
c++·适配器模式
jrrz08281 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
咖啡里的茶i1 小时前
Vehicle友元Date多态Sedan和Truck
c++
海绵波波1071 小时前
Webserver(4.9)本地套接字的通信
c++
@小博的博客1 小时前
C++初阶学习第十弹——深入讲解vector的迭代器失效
数据结构·c++·学习
爱吃喵的鲤鱼2 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
DARLING Zero two♡3 小时前
关于我、重生到500年前凭借C语言改变世界科技vlog.16——万字详解指针概念及技巧
c语言·开发语言·科技
7年老菜鸡3 小时前
策略模式(C++)三分钟读懂
c++·qt·策略模式
Ni-Guvara3 小时前
函数对象笔记
c++·算法
似霰3 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder