qsort()和bsearch()

本文详细介绍了C语言中的排序函数qsort()和二分查找函数bsearch()。qsort()用于对数组进行排序,其排序算法依赖于提供的比较函数compar。bsearch()则在已排序的数组中通过二分查找找到指定元素。两者都使用compar函数进行元素间的比较。文章还涵盖了这两个函数的参数、返回值、复杂度、数据竞争和异常情况。

qsort

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

Sort elements of array

Sorts the num elements of the array pointed to by base, element size, each element size bytes long, using the compar function to determine the order.

The sorting algorithm used by this function compares pairs of elements by calling the specified compar function with pointers to them as argument.(函数指针作为参数)

The function does not return any value, but modifies the content of the array pointed to by base reordering its elements as defined by compar.

The order of equivalent elements is undefined.

 

Parameters

1.base

Pointer to the first object of the array to be sorted, converted to a void*.

2.num

Number of elements in the array pointed to by base.
size_t is an unsigned integral type.

3.size

Size in bytes of each element in the array.
size_t is an unsigned integral type.

4.compar

Pointer to a function that compares two elements.
This function is called repeatedly by qsort to compare two elements. It shall follow the following prototype:

int compar (const void* p1, const void* p2);


Taking two pointers as arguments (both converted to const void*). The function defines the order of the elements by returning (in a stable and transitive manner):

return valuemeaning
<0The element pointed to by p1 goes before the element pointed to by p2
0The element pointed to by p1 is equivalent to the element pointed to by p2
>0The element pointed to by p1 goes after the element pointed to by p2


For types that can be compared using regular relational operators, a general compar function may look like:

int compareMyType (const void * a, const void * b)
{
  if ( *(MyType*)a <  *(MyType*)b ) return -1;
  if ( *(MyType*)a == *(MyType*)b ) return 0;
  if ( *(MyType*)a >  *(MyType*)b ) return 1;
}

 

Return Value

none

 

Example

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

int values[] = { 40, 10, 100, 90, 20, 25 };

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

int main ()
{
  int n;
  qsort (values, 6, sizeof(int), compare);
  for (n=0; n<6; n++)
     printf ("%d ",values[n]);
  return 0;
}



Output:

10 20 25 40 90 100

 

Complexity

Unspecified, but quicksorts are generally linearithmic in num, on average, calling compar approximately num*log2(num)times.

 

Data races

The function accesses and/or modifies the num elements in the array pointed to by base.

 

Exceptions (C++)

If comp does not throw exceptions, this function throws no exceptions (no-throw guarantee).

If base does not point to an array of at least num*size bytes, or if comp does not behave as described above, it causes undefined behavior.

 


bsearch

void* bsearch (const void* key, const void* base,
               size_t num, size_t size,
               int (*compar)(const void*,const void*));

Binary search in array

Searches the given key in the array pointed to by base (which is formed by num elements, each of size bytes), and returns a void* pointer to a matching element, if found.

To perform the search, the function performs a series of calls to compar with key as first argument and elements of the array pointed to by base as second argument.

Because this function may be optimized to use a non-linear search algorithm (presumably a binary search), the elements that compare less than key using compar should precede those that compare equal, and these should precede those that compare greater. This requirement is fulfilled by any array ordered with the same criteria used by compar(as if sorted with qsort).

 

Parameters

key

Pointer to the object that serves as key for the search, type-casted to a void*.

base

Pointer to the first object of the array where the search is performed, type-casted to a void*.

num

Number of elements in the array pointed to by base.
size_t is an unsigned integral type.

size

Size in bytes of each element in the array.
size_t is an unsigned integral type.

compar

Pointer to a function that compares two elements.
This function is called repeatedly by bsearch to compare key against individual elements in base. It shall follow the following prototype:

int compar (const void* pkey, const void* pelem);


Taking two pointers as arguments: the first is always key, and the second points to an element of the array (both type-casted to const void*). The function shall return (in a stable and transitive manner):

return valuemeaning
<0The element pointed to by pkey goes before the element pointed to by pelem
0The element pointed to by pkey is equivalent to the element pointed to by pelem
>0The element pointed to by pkey goes after the element pointed to by pelem


For types that can be compared using regular relational operators, a general compar function may look like:

int compareMyType (const void * a, const void * b)
{
  if ( *(MyType*)a <  *(MyType*)b ) return -1;
  if ( *(MyType*)a == *(MyType*)b ) return 0;
  if ( *(MyType*)a >  *(MyType*)b ) return 1;
}

 

Return Value

A pointer to an entry in the array that matches the search key. If there are more than one matching elements (i.e., elements for which compar would return 0), this may point to any of them (not necessarily the first one).
If key is not found, a null pointer is returned. 

 

Example

/* 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;
}



In the example, compareints compares the values pointed to by the two parameters as int values and returns the result of subtracting their pointed values, which gives 0 as result if they are equal, a positive result if the value pointed to by ais greater than the one pointed to by b or a negative result if the value pointed to by b is greater.

In the main function the target array is sorted with qsort before calling bsearch to search for a value.

Output:

40 is in the array.


For C strings, strcmp can directly be used as the compar argument for bsearch:

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

char strvalues[][20] = {"some","example","strings","here"};

int main ()
{
  char * pItem;
  char key[20] = "example";

  /* sort elements in array: */
  qsort (strvalues, 4, 20, (int(*)(const void*,const void*)) strcmp);

  /* search for the key: */
  pItem = (char*) bsearch (key, strvalues, 4, 20, (int(*)(const void*,const void*)) strcmp);

  if (pItem!=NULL)
    printf ("%s is in the array.\n",pItem);
  else
    printf ("%s is not in the array.\n",key);
  return 0;
}



Output:

example is in the array.

 

Complexity

Unspecified, but binary searches are generally logarithmic in num, on average, calling compar approximately log2(num)+2 times.

 

Data races

The function accesses the object pointed to by key and any number of the num elements in the array pointed to by base, but does not modify any of them.

 

Exceptions (C++)

If comp does not throw exceptions, this function throws no exceptions (no-throw guarantee).

If key does not point to an object size bytes long, or if base does not point to an array of at least num properly arranged elements of size bytes each, or if comp does not behave as described above, it causes undefined behavior.

<think>首先,用户要求用中文回答问题。问题是:“介绍c语言中的qsort函数”。我需要介绍C语言中的qsort函数。 qsort函数是C标准库中的一个函数,用于对数组进行快速排序。它在stdlib.h头文件中声明。函数原型是: void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); - base:指向数组第一个元素的指针。 - nmemb:数组中元素的数量。 - size:每个元素的大小(以字节为单位)。 - compar:指向比较函数的指针,该函数用于决定元素间的顺序。 比较函数应该返回负数、零或正数,分别表示第一个参数小于、等于或大于第二个参数。 在回答中,我应该用中文解释这些内容。然后,在回答结束后,必须提出3-5个相关问题,并以“§§相关问题§§”开头。相关问题必须基于我的回答用户的问题。 确保输出格式正确:回答内容后,直接输出“§§相关问题§§”,然后列出3-5个问题,每个问题用数字点号(如1. ···)表示,禁止换行分散,意思是问题之间不要有空行。 从示例中,我看到在代码块后直接输出“§§相关问题§§”,然后列出问题。 我的回答应该包括一个简单的代码示例来展示qsort的使用,类似于示例中的Python代码。 所以,我会写一个C语言的代码示例,展示如何使用qsort。 例如: ```c #include <stdio.h> #include <stdlib.h> // 比较函数,用于整数 int compare(const void *a, const void *b) { return (*(int*)a - *(int*)b); } int main() { int arr[] = {5, 2, 8, 1, 3}; int n = sizeof(arr) / sizeof(arr[0]); qsort(arr, n, sizeof(int), compare); for (int i = 0; i < n; i++) { printf("%d ", arr[i]); } return 0; } ``` 这个示例展示了如何对一个整数数组进行排序。 现在,构建回答: 1. 介绍qsort函数:它是C标准库中的快速排序实现。 2. 解释参数:base, nmemb, size, compar。 3. 提供代码示例。 4. 结束回答。 5. 输出“§§相关问题§§”。 6. 列出3-5个相关问题。问题应该基于qsort函数,比如它的工作原理、使用注意事项、与其他排序函数的比较等。 可能的§§相关问题§§: 1. qsort函数的时间复杂度是多少? 2. 如何为自定义结构体使用qsort函数? 3. qsort函数是稳定的排序算法吗? 4. 在C语言中,qsortbsearch函数有什么关系? 5. 使用qsort时需要注意哪些常见错误? 确保有3-5个问题。 最后,输出格式:回答内容后直接是“§§相关问题§§”,然后问题列表。</think>C语言中的`qsort`函数是标准库`stdlib.h`中提供的通用排序函数,基于快速排序算法实现。它允许对任意数据类型的数组进行排序,通过指定比较函数来实现自定义排序逻辑。函数原型如下: ```c void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); ``` 参数说明: - `base`:指向数组首元素的指针(数组起始地址)。 - `nmemb`:数组中元素的数量。 - `size`:每个元素的大小(以字节为单位)。 - `compar`:函数指针,指向自定义的比较函数;该函数应返回负数(表示第一个参数小于第二个)、零(表示相等)或正数(表示大于)。 比较函数必须定义为: ```c int compar(const void *a, const void *b); ``` 其中,`a``b`是指向数组中元素的指针,需要根据数据类型进行类型转换。 ### 示例代码 以下是一个排序整数数组的简单示例: ```c #include <stdio.h> #include <stdlib.h> // 比较函数(升序排序) int compare_ints(const void *a, const void *b) { int arg1 = *(const int*)a; int arg2 = *(const int*)b; if (arg1 < arg2) return -1; if (arg1 > arg2) return 1; return 0; } int main() { int arr[] = {5, 2, 9, 1, 6}; size_t n = sizeof(arr) / sizeof(arr[0]); qsort(arr, n, sizeof(int), compare_ints); // 调用qsort排序 for (size_t i = 0; i < n; i++) { printf("%d ", arr[i]); // 输出: 1 2 5 6 9 } return 0; } ``` 特点: - **通用性强**:可排序任何数据类型(如结构体)。 - **效率高**:平均时间复杂度为O(n log n),但最坏情况可能退化到O(n²)。 - **不稳定**:相同元素的顺序可能改变。 - **使用注意**:比较函数必须正确处理所有边界情况,否则可能导致未定义行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值