C语言入门——二分查找

 二分查找也称折半查找,它是一种效率较高的查找方法

例:在一个有序数组中查找具体的某个数字n,

        如,在一个一维数组中存储了一组有序元素1 2 3 4 5 6 7 8 9 10,现在我们要查找数字7,有人会想从前往后遍历去查找,这样固然可行,但是如果数据元素不是10个,而是一千甚至一万,则这样的查找效率显得很低

        这里我们忽略了这组元素是有序的,我们可以从这组数据的中间开始查找,取中间的元素与要查找的元素比较大小,这样一次比较可以排除一半的元素,显然效率比遍历更高,这就是我们要说的二分查找,又称为折半查找

如在1 2 3 4 5 6 7 8 9 10查找7

C语言入门——二分查找_第1张图片

我们查找的思路如下:

首先找到这组元素的中间元素:最左边元素的下标和最右边元素的下标之和除以2,作为中间元素的下标,如本例,(9+0)/ 2 = 4,4作为中间元素的下标,对应的数字是5

5比要找的数字7小,被查找的范围变为6 7 8 9 10;

新的被查找的范围的中间元素的下标(5+9)/ 2 = 7,对应的数字是8

8比要找的数字8大,被查找的范围6 7;

新的被查找的范围的中间元素的下标(5+6)/ 2 = 5,对应的数字是6

6比要找的数字7小,被查找的范围7;

新的被查找的范围的中间元素的下标(6+6)/ 2 = 6,对应的数字是7,找到了

我们发现上面算法只找了4次就找到了所要找的元素,如果是遍历的话,最坏的情况要找10次,所以二分查找其效率较高,其时间复杂度为log_{2}n

用代码实现:

#include 
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int k = 7;            //要查找的数字
    //在数组中查找k
    int sz = sizeof(arr) / sizeof(arr[0]);    //数组元素个数
    int left = 0;
    int right = sz -1;
    while(left <= right)
    {
        int mid = (left + right) / 2;
        if(arr[mid] < k)
        {
            left = mid + 1;
        }
        else if(arr[mid] > k)
        {
            right = mid - 1;
        }
        else
        {
            printf("找到了:%d,其下标是:%d\n",arr[mid],mid);
            break;
        }
    }
    if(left > right)
    {
        printf("找不到\n");
    }
    return 0;
}

 我们运行可以得到:

当把k改为11 ,我们发现找不到


如果上述代码要用函数实现,我们需要注意

如果函数内部需要参数部分传递某个数组元素的个数,数组元素个数要在函数外部求

如果在函数内部求数组元素个数,因为数组名传参传递的是数组名的首元素地址,此时sizeof(arr)算出的结果为4,sizeof(arr) / sizeof(arr[0])算出的结果为1,而不是元素个数,这点需要注意

用函数实现一个整型有序数组的二分查找:

#include 
int binary_search(int a[], int k, int s)
{
    int left = 0;
    int right = s - 1;
    while(left <= right)
    {
        int mid = (left + right) / 2;
        if(k < a[mid])
        {
            right = mid - 1;
        }
        else if(k > a[mid])
        {
            left =mid + 1;
        }
        else
        {
            return mid;
            break;
        }
    }
    return -1;
}
int main()
{
    int arr[] = {1,2,3,4,5,6,7,8,9,10};
    int k = 0;
    printf("输入要查找的数:");
    scanf("%d",&k);
    int sz = sizeof(arr) / sizeof(arr[0]);
    //找到就返回找到的位置的下标
    //找不到就返回-1
    int ret = binary_search(arr, k, sz);
    if (ret == -1)
    {
        printf("找不到\n");
    }
    else
    {
        printf("找到了:%d,下标是:%d\n",arr[ret],ret);
    }
    return 0;
}

 运行结果如下:

你可能感兴趣的:(C语言入门,算法,c语言,数据结构)