C标准库中是否有二进制搜索方法?

时间:2019-07-10 08:24:18

标签: c algorithm binary-search standard-library

我找不到任何实现二进制搜索的方法。是因为我找不到它,还是因为它不存在?

我想第二点,但是我找不到重复的问题,所以也许我错了。

2 个答案:

答案 0 :(得分:13)

hereherehere中列出的同一bsearch()中有一种<stdlib.h>方法。

bsearch()函数使用二进制搜索算法来查找与大小为n个元素的排序数组中的键匹配的元素。 (在<stdlib.h>中将size_t类型定义为无符号整数。)最后一个参数comparebsearch()提供了指向该函数的指针,该函数调用该函数将搜索键与任何数组元素进行比较。此函数必须返回一个值,该值指示其第一个参数(搜索关键字)是否小于,等于或大于其第二个参数(要测试的数组元素)。

通常应在qsort()之前使用bsearch(),因为数组排序(应以升序排列,并用相同的顺序compare使用的搜索标准。此步骤是必需的,因为二进制搜索算法会测试搜索关键字是高于还是低于数组的中间元素,然后删除数组的一半,测试结果的中间,再删除一半,依此类推。如果您为bsearch()的比较函数定义了两个参数相同的类型,那么qsort()可以使用相同的比较函数。

bsearch()函数返回一个指向与搜索键匹配的数组元素的指针。如果找不到匹配的元素,则bsearch()返回空指针。 [a]

示例用法

/* bsearch example */
#include <stdio.h>      /* printf */
#include <stdlib.h>     /* qsort, bsearch, NULL */

int compareints (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

int values[] = { 50, 20, 60, 40, 10, 30 };

int main ()
{
  int * pItem;
  int key = 40;
  qsort (values, 6, sizeof (int), compareints);
  pItem = (int*) bsearch (&key, values, 6, sizeof (int), compareints);
  if (pItem!=NULL)
    printf ("%d is in the array.\n",*pItem);
  else
    printf ("%d is not in the array.\n",key);
  return 0;
}

输出:

  

40在数组中。

针对下面的评论,有关如何查找小于/大于key的第一个元素,这是(可能很脏)解决方法:您可以遍历排序后的数组,并使用传递给此方法的相同key函数将其元素与compare进行比较,直到找到一个小于/大于key的元素。

答案 1 :(得分:3)

C库具有在bsearch中声明的标准函数<stdlib.h>,用于此目的:根据给定的比较函数,在按升序排序的条目表中找到匹配的条目。

这是C标准中的规范:

  

7.22.5.1 bsearch功能

     

简介

#include <stdlib.h>
void *bsearch(const void *key, const void *base,
              size_t nmemb, size_t size,
              int (*compar)(const void *, const void *));
     

说明

     

bsearch函数在nmemb对象的初始元素由base指向的数组中搜索与{{1}指向的对象匹配的元素}。数组每个元素的大小由key指定。

     

size所指向的比较函数将使用两个参数依次调用,这两个参数分别指向键对象和数组元素。如果分别认为键对象小于,匹配或大于数组元素,则函数应返回小于,等于或大于零的整数。数组应包括:所有小于等于的元素,所有等于等于的元素以及所有大于等于键对象的元素,按此顺序。 308)

     

返回

     

compar函数返回一个指向数组匹配元素的指针,如果找不到匹配项,则返回空指针。 如果两个元素比较相等,则未指定匹配的元素。

     
     

308)实际上,整个数组是根据比较函数进行排序的。

此功能有2个缺点:

  • 如果该表包含重复的匹配条目,则未指定将返回哪个条目,如上面最后一段所强调的那样。
  • 如果在表中找不到该函数,则该函数不能用于定位插入该项的位置,它只会返回空指针。

这是修复第一个点的简单实现(编码为始终返回最接近数组开头的匹配项),并且可以修改以解决第二个问题:

bsearch