C语言库函数qsort及bsearch快速排序算法使用解析

 更新时间:2022年02月14日 11:32:05   作者:乔乔家的龙龙  
这篇文章主要为大家介绍了C语言库函数qsort及bsearch快速排序算法的使用示例解析

qsort

qsrot 就是C语言库函数中的快速排序函数,对数组,结构体都可以实现快速排序, 他在头文件<stdlib.h>中使用,声明格式为:

void qsort(void* base, size_t nums, size_t size, int (*compare)(const void *, const void*))

这么烦人一长串的参数各是什么意思呢,base 是指向要排序的数组的第一个元素的指针。nums是由 base 指向的数组中元素的个数。size 是数组中每个元素的大小,以字节为单位。compare 是用来比较两个元素的函数,这个比较函数需要我们自己补全。

含义

void*代表着任意类型的数组,这个数组也就是我们想用来排序的对象数组;size_t 在系统里面被定义成 int 类型的,所以我们可以把 size_t修饰的数默认为一个整数。

为什么要细化出数组大小和元素大小?这和我排序有毛关系?其实这是为了区分不同类型的数组,int 和 char 类型的数组每个元素所占空间就不一样,自然要区别开。

int main()
{
	int arr[6] = { 1,4,5,8,2,3};
	qsort(arr, 6, sizeof(arr[0]), compare);
}

最后的 compare 函数我是直接将这个元素作为参数传进来,那么问题来了,这个比较函数怎么写?

我们根本不用管那个 *compare 的指针什么鬼,他就相当于告诉你这里在用一个外部函数,我们只要明白整个函数名儿上去就是妥妥的了,这个函数名不一定就叫 compare ,诸君自便。

实现

后面的(const void , const void)自然就是这个函数的参数了,两个 void* 实际运用的时候就看成 a ,b,既然是外部函数我们就要自己动手了,我们的最终目的是为了排序,比较函数就应该实现数组元素大小的比较,本质上说就是在比较 a和b 的大小,而a,b是我数组中任意的两两元素。

那首先要做的就是把这个不知道什么类型的 void 指针变成我们给定的,之前代码中给的是整型数组,这里就要对应变成整型指针,这两个指针指向数组中的两个整数,既然要比较,我们就直接做减法看正负即可,把这两个指针转换成真正的整数后就大功告成了:

	int* p = (int*)a;
	int* q = (int*)b;
	int c = *p;
	int d = *q;

成品如下:

#include<stdlib.h>
int compare(const void* a,const void* b)
{
	int* p = (int*)a;
	int* q = (int*)b;
	int c = *p;
	int d = *q;
	return c - d;
}
int main()
{
	int i = 0;
	int arr[6] = { 1,4,5,8,2,3 };
	qsort(arr, 6, sizeof(arr[0]), compare);
	for (i = 0; i < 6; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

结果如下

在这里插入图片描述

结构体的排序也是同理,如下:

#include<stdlib.h>
int compare(const void* a,const void* b)
{
	int* p = (int*)a;
	int* q = (int*)b;
	int c = *p;
	int d = *q;
	return c - d;
}
int main()
{
	int i = 0;
	int arr[6] = { 1,4,5,8,2,3 };
	qsort(arr, 6, sizeof(arr[0]), compare);
	for (i = 0; i < 6; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

结果就是根据结构体中 a 成员大小来排的:

在这里插入图片描述

格局打开

1.上面是实现从小到大排列,要实现从大到小排只需 return d - c 即可。
2.如果是比较浮点数,注意在两个数相差不大时,介于(-1,1),因为现在是整型指针,返回值也是整型,return 回来的就是个 0,造成无意义操作,怎么处理呢?很简单,改成如下即可:

int compare(const void* a,const void* b)
{
	int* p = (int*)a;
	int* q = (int*)b;
	int c = *p;
	int d = *q;
	if(c - d<0)
	{
	return -1;
	}
	else
	{
	return 1;
	}
}

bsearch

bsearch (binary search)也是C语言库函数,功能是执行二分查找,声明定义如下

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

和 qsort 一样是又臭又长,且随我慢慢看,key 是指向要查找的元素的指针,类型转换为 void*,其他的和 qsort 里的是一样的不再赘述。

强调一下,bsearch()的使用有一个硬性要求,这个数组必须要有顺序性,从大到小或从小到大否则达咩,所以建议和 qsort 配套实验更佳。

这个 key 就是我们的查找目标,void* 代表着一个指针,所以我们在函数里面是不能直接给出的 key 的值,那我们就取他对应的地址就行

	int key = 5;
	bsearch(&key,arr,6,sizeof(int),compare1);

接下来顺水推舟验证一下:

 judge = (int*) bsearch (&key, values, 5, sizeof (int), cmpfunc);
   if( judge != NULL ) 
   {
      printf("find %d is true\n", *judge);
   }
   else 
   {
      printf("%d can not be found\n", *judge);
   }
   
   return(0);
}

整个代码如下:

#include<stdlib.h>
int compare(const void* a, const void* b)
{
	int* p = (int*)a;
	int* q = (int*)b;
	int c = *p;
	int d = *q;
	return c - d;
}
int compare1(const void* key, const void* a)
{
	return (*(int*)key-*(int*)a);
}
int main()
{
	int* judge;
	int arr[6] = { 1,4,5,8,2,3 };
	qsort(arr, 6, sizeof(arr[0]), compare);
	int key = 5;
	judge = (int*)bsearch(&key, arr, 5, sizeof(int), compare1);
	if (judge != NULL)
	{
		printf("find %d is true\n", *judge);
	}
	else
	{
		printf("%d can not be found\n", *judge);
	}

	return(0);
}

在这里插入图片描述

今天就先到这里吧,摸了家人们,更多关于C语言库函数qsort及bsearch快速排序算法的资料请关注脚本之家其它相关文章!

相关文章

  • 详解C++中vector的理解以及模拟实现

    详解C++中vector的理解以及模拟实现

    vector是表示可变大小数组的序列容器。这篇文章主要为大家详细介绍了vector的理解以及模拟实现,文中的示例代码讲解详细,感兴趣的可以了解一下
    2023-03-03
  • C语言三种方法解决轮转数组问题

    C语言三种方法解决轮转数组问题

    这篇文章主要给大家讲解轮转数组的问题,一个问题不局限于一种解法,希望你看了本文的解决方法以后可以举一反三自己编写,这样你的技术水平会有质的提高
    2022-04-04
  • C++中auto类型说明符详解(附易错实例)

    C++中auto类型说明符详解(附易错实例)

    这篇文章主要给大家介绍了关于C++中auto类型说明符的相关资料,文中还附易错实例,在C++11中引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型,需要的朋友可以参考下
    2023-07-07
  • C语言、C++中的union用法总结

    C语言、C++中的union用法总结

    这篇文章主要介绍了C语言、C++中的union用法总结,本文讲解了什么是union、C中使用union、当union遇到对象等内容,需要的朋友可以参考下
    2014-10-10
  • C语言学习笔记之VS2022安装使用教程

    C语言学习笔记之VS2022安装使用教程

    这篇文章主要介绍了C语言学习笔记之VS2022安装使用教程,在VS2022中,在使用scanf函数编译出错,本文给大家提到了解决方法,需要的朋友可以参考下
    2022-05-05
  • C语言实现返回字符串函数的四种方法

    C语言实现返回字符串函数的四种方法

    在C语言中实现函数返回字符串,首先要确定函数返回的字符串地址的来源,一般分为四种方式,下面这篇文章就给大家通过示例代码详细介绍这几种方法,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-12-12
  • C++动态内存分配超详细讲解

    C++动态内存分配超详细讲解

    给数组分配多大的空间?你是否和初学C时的我一样,有过这样的疑问。这一期就来聊一聊动态内存的分配,读完这篇文章,你可能对内存的分配有一个更好的理解
    2022-08-08
  • MFC实现连连看游戏之地图显示

    MFC实现连连看游戏之地图显示

    这篇文章主要为大家详细介绍了MFC实现连连看游戏之地图显示,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Visual Studio Code (vscode) 配置C、C++环境/编写运行C、C++的教程详解(Windows)【真正的小白版】

    Visual Studio Code (vscode) 配置C、C++环境/编写运行C、C++的教程详解(Windows

    这篇文章主要介绍了Visual Studio Code (vscode) 配置C、C++环境/编写运行C、C++的教程详解(Windows)【真正的小白版】,图文详解介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • C++实现LeetCode(118.杨辉三角)

    C++实现LeetCode(118.杨辉三角)

    这篇文章主要介绍了C++实现LeetCode(118.杨辉三角),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07

最新评论