目录
一、qsort快速排序函数
1.1定义
void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
1.2功能
对一组数据(整型数据、字符串、结构体等)进行排序。
1.3参数
base:是首元素的地址
num:数组元素个数
size:元素类型大小(sizeof)
int (*compar)(const void*a,const void*b):是用来比较待排序数据中的两个元素的函数,这个函数的两个参数是待排序任意类型数据中两个元素的地址,这个函数由qsort函数反复调用,以比较两个元素。如果*a<*b,返回值-1;如果*a>*b,返回值1;如果*a==*b,返回值为0。
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;
}
注意:待比较排序的数据必须为同一类型,就好比待比较排序的是一个数组,存放的是相同类型的数据
二、通过不同类型的数据来举例进行qsort快速排序
2.1整形数据
#include <stdio.h>
#include <stdlib.h> //qsort函数
int arr[] = { 40, 10, 100, 90, 20, 25 };
int compare (const int * a, const int * b)//compare比较函数比较的是一个int型的数组中的元素
{
return ( *a - *b );//进行一个升序排序,降序改为*b-*a即可
//当比较函数两参数前大后小,返回值大于0.前小后大返回值小于0,两种相等返回值等于0。 //这样就实现了升序排序。
}
int main ()
{
int arr[] = { 40, 10, 100, 90, 20, 25 };
int n;
qsort (arr, 6, sizeof(int), compare);
//arr即首元素地址,6是元素个数,sizeof(int)求一个元素的大小,再加上调用compare比较函数
for (n=0; n<6; n++)//输出排序后的元素
{
printf ("%d ",arr[n]);
}
return 0;
}
通过代码就对qsort快速排序函数有了一个认知,为了方便后面字符串和结构体的排序我就不加注释了。
2.2字符串排序
字符串排序的比较原理:对两字符串对应每一元素ASSCII码值逐个比较(当出现某一位不相同时,ASCII码值大的整个字符串就大),原理同strcmp函数。
#include <stdio.h>
#include <string.h> //strcmp函数
#include <stdlib.h> //qsort函数
int compar(char** a, char** b)
{
return strcmp(*a,*b); //用strcmp实现字符串排序
}
int main()
{
int n = 0;
char* ch[] = { "love","ljy","qinqin","hbhb" };
qsort(ch,4,sizeof(char*),compar);
for(n = 0;n < 4; n++)
{
printf("%s ",ch[n]);
}
return 0;
}
2.3结构体排序
需要先确定用结构体中的哪一组数据进行排序,比如一个学生,我们可以用姓名排序(即字符串排序),用年龄(即int整形数据排序),这样也就同前两种排序方法,只不过调用的compar函数不同罢了。
三、自主实现qsort函数
3.1实现myqsort函数(包含调用cmp比较函数和swap交换函数)
//实现qsort函数
void my_qsort(void* base,int sz,int width,int (*cmp)(const void*p1, const void*p2) )
{
int i = 0;
//趟数
for (i = 0; i < sz - 1; i++)
{
//每一趟的排序次数
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
//两个元素比较
//arr[j] arr[j+1]
//这里因为我们不知道待比较元素的类型,我们通过强制转换,把元素转换成(char*)类型
//这样我们用(j+1)*width就可以完美指向到下一个元素。
if (cmp( (char*)base+j*width, (char*)base+(j+1)*width )>0)
{
//交换
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
3.2实现交换函数
//因为我们不知道元素类型,所以我们还是一个字节一个字节交换
void Swap(char*buf1, char*buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
3.3实现compor比较函数
其实我们在第二板块,已经将compor函数实现了,就是需要将整形数据的比较方法,和字符串的比较方法。通过返回值来判断大小即可。