欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

二分查找及其变种问题

程序员文章站 2022-07-08 13:21:58
...

基本的二分查找

代码实现

非递归版本

#include<stdio.h>
int binary_search(int a[], int low,int high,int val)
{
    int mid;
    while(low<=high)
    {
        mid = low + high / 2;
        if(a[mid]>val)
        {
            high = mid - 1;
        }else if(a[mid]==val)
        {
            return mid;
        }else
        {
            low = high + 1;
        }

    }
    return -1;
}
int main()
{
    int a[5] = {1, 3, 5, 7, 9};
    printf("%d", binary_search(a, 0, 4, 5));
}

递归版本

#include <stdio.h>
int binary_search(int a[], int low, int high, int val)
{
    int mid;
    if (low <= high)
    {
        mid = low + high / 2;
        if (a[mid] > val)
        {
            return binary_search(a, low, mid - 1, val);
        }
        else if (a[mid] == val)
        {
            return mid;
        }
        else
        {
            return binary_search(a, mid + 1, high, val);
        }
    }
    if(low>high)
    {
        return -1;
    }
}
int main()
{
    int a[5] = {1, 3, 5, 7, 9};
    printf("%d", binary_search(a, 0, 4, 10));
}

二分查找比较简单就不再赘述。

变种问题

查找第一个等于给定值的元素

过程描述

普通的二分查找只能保证找到给定值元素的位置,并不能保证位置唯一或者出现的顺序,通过改变二分查找的代码部分内容,可以实现。

二分查找及其变种问题
当我们a[mid]=val的时候,此时我们就可以通过判断mid前面一位的元素是否也为给定值,如果是的话,那就将high移动到mid前一位(图上情况是正好只有mid前一位为指定值,实际上a[1]也可能为给定值),在low和high(mid-1)之间再次二分查找。如果mid前一位元素不等于给定值,说明mid就是第一次出现的位置(因为这是个有序的数组,前面一位如果不等于的话,那就一定小于给定值)

代码实现
#include<stdio.h>
int binary_search(int a[], int low,int high,int val)
{
    int mid;
    if(low<=high)
    {
        mid = low + high / 2;
        if(a[mid]>val)
        {
            binary_search(a, mid + 1, high, val);
        }else if(a[mid]==val)
        {
            if (a[mid - 1] == val)
            {
                return binary_search(a, low, mid - 1, val);
            }
                return mid;
        }else
        {
            high = mid - 1;
            return binary_search(a, low, mid-1, val);
        }

    }
    if(low>high)
    {
		return -1;
    }
    
}
int main()
{
    int a[6] = {1, 2, 3, 3, 3, 5};
    printf("%d", binary_search(a, 0, 5, 3));
}

二分查找及其变种问题

查找最后一个等于给定值的元素

过程描述

理解了第一种变体,这一种就很好理解了,就不做过多解释。

代码实现
#include<stdio.h>
int binary_search(int a[], int n,int val)
{
    int low = 0;
    int high = n - 1;
    int mid = 0;
    while(low<=high)
    {
        mid = (low + high) / 2;//记得打括号还可以转化成别的两种写法1.high-(high-low)/2
        if(a[mid]>val)			//2.low + ((high - low) >> 1).可以加快运行速度,防止溢出
            high = mid - 1;
        else if(a[mid]==val)
        {
            if((a[mid+1]!=val)||(mid==n-1))
            {
                return mid;
            }else
            {
                low = mid + 1;
            }
        }else
        {
            low = mid + 1;
        }

    }
    return -1;
}
int main()
{
    int a[6] = {1, 2, 3, 3, 3, 5};
    printf("the last position:%d", binary_search(a, 6,3));
}

二分查找及其变种问题

查找第一个大于等于给定值的元素

过程描述

对于这种进行一下解释。如图所示。
二分查找及其变种问题

代码实现
#include<stdio.h>
int binary_search(int a[], int n,int val)
{
    int low = 0;
    int high = n - 1;
    int mid = 0;
    while(low<=high)
    {
        mid = (low + high) / 2;
        if(a[mid]<val)
        {
            low = mid + 1;
        }else
        {
            if(a[mid-1]<val||mid==0)
            {
                return mid;
            }else
            {
                high = mid - 1;
            }
        }

    }
    return -1;
}
int main()
{
    int a[6] = {1, 2, 3, 3, 3, 5};
    printf("the last position:%d", binary_search(a, 6,4));
}

二分查找及其变种问题

查找最后一个小于等于给定值的元素

过程描述

理解了上述图片,这个就不需要多余赘述了,可以自己推理一下检验一下是否掌握了

代码实现
#include<stdio.h>
int binary_search(int a[], int n,int val)
{
    int low = 0;
    int high = n - 1;
    int mid = 0;
    while(low<=high)
    {
        mid = (low + high) / 2;
        if(a[mid]<=val)
        {
            if(a[mid+1]>val ||mid==n-1 )
            {
                return mid;
            }else{
            low = mid + 1;
            }
        }else
        {
            high = mid - 1;
        }

    }
    return -1;
}
int main()
{
    int a[6] = {1, 2, 3, 3, 3, 5};
    printf("the last position:%d", binary_search(a, 6,4));
}

二分查找及其变种问题

相关标签: 算法 c语言