C语言使用函数qsort进行快速排序(整形排序,字符串排序,结构体排序)

平常写题目时,总要用到排序,以至于自己把冒泡排序和选择排序函数都保存了,需要的时候调用,但是只能用于整形,那么有没有什么函数能实现各个类型的快速排序呢?其实C的库函数里面就自带了。

 

先看摘要

void qsort( void *base,        //待排元素的起始位置
            size_t num,        //数组的元素个数
            size_t width,      //一个元素的字节大小
            int (*cmp)(const void *e1, const void *e2 ) );   //函数指针 (返回的值 <0 ==0 或者 >0)
                   ↑
            //  比较函数        e1 和 e2为待比较的两个元素的地址

 标题说了,qsort函数能对多种类型进行比较,那么函数的做作者如何知道我们需要比较的类型呢?最重要的就在于自定义的那个函数。

我们先看一下整形的排序

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* e1, const void* e2)
{
	if (*(int*)e1 > *(int*)e2)
		return 1;
	else if (*(int*)e1 == *(int*)e2)
		return 0;
	else
		return -1;
}
int main()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	//排序为升序
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果为0 1 2 3 4 5 6 7 8 9

有同学可能要问了,不就一个整形排序吗?有必要弄得这么麻烦吗?

先别着急,先把原理弄懂。

int cmp_int(const void* e1, const void* e2)
{
	if (*(int*)e1 > *(int*)e2)   

    //前面提问了
    //作者怎么知道我们排序的类型就是通过函数
    //void* 可以存放任何类型的指针
    //我们排什么类型,就强制转化成什么类型
    //比如这里排序整形,就强制转化成int*类型。

		return 1;
	else if (*(int*)e1 == *(int*)e2)
		return 0;
	else
		return -1;
}

既然我们要返回的值只有三种情况,我们可以简化一下这个函数

int cmp_int(const void* e1, const void* e2)
{
	return (*(int*)e1 - *(int*)e2);
}

相信看到这里,你已经对qsort有了初步的了解。

我们再看进阶一点的字符串排序

输入10个等长的字符串,进行从小到大排序,然后输出排序后的10个字符串,使用指针来实现。

###输入格式:

输入十行,每行为一个字符串,字符串中不包含空格。

###输出格式:

输出排序后的字符串。

输入样例:

在这里给出一组输入。例如:

pklnsr
olzxni
rigyqo
pgirjr
jbwgvs
mswgrx
jvrfuo
plmppk
leowfm
jdnuog

输出样例:

在这里给出相应的输出。例如:

jbwgvs
jdnuog
jvrfuo
leowfm
mswgrx
olzxni
pgirjr
pklnsr
plmppk
rigyqo

代码如下

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct str{
	char arr[10];
};
int sort1(const void* e1, const void* e2)
{
	return strcmp(((struct str*)e1)->arr, ((struct str*)e2)->arr);
}

int main()
{
	int i = 0;
	struct str arr[10];
	for (i = 0; i < 10; i++)
		scanf("%s", arr[i].arr);
	qsort(arr, 10, sizeof(arr[0]), sort1);
	for (i = 0; i < 10; i++)
		printf("%s\n", arr[i].arr);
	return 0;
}

在这里,我们用结构体存放十个字符串,用qsort函数进行排序,应为我们运用的是结构体,所以就强制转换成结构体类型(struct str*)。

来考考你,记住qsort函数了吗?

qsort(arr,  //数组
      10,   //元素个数
      sizeof(arr[0]),  //一个元素字节大小
      sort1);  //比较函数
int sort1(const void* e1, const void* e2)
{
	return strcmp(((struct str*)e1)->arr, ((struct str*)e2)->arr);
}

自定义的函数强制转化成我们想要的类型,此处是从小到大排序,如果想要从大到小,只需将return后面的两个数据调换一下位置就行了。

记住这些,我们就可以运用qsort排序了。

接下来看结构体排序

7-2 成绩排序 (10 分)

输入格式:

输入一个正整数n(n<50),下面n行输入n个学生的信息,包括:学号、姓名、成绩。

输出格式:

输出从高到低排序后的学生信息,包括:学号、姓名、成绩。

输入样例:

在这里给出一组输入。例如:

3
101 Zhang 78
102 Wang 91
103 Li 85

输出样例:

在这里给出相应的输出。例如

102 Wang 91
103 Li 85
101 Zhang 78

代码如下

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Student
{
    int a;
    char name[50];
    int score;
};
int compare(const void* e1, const void* e2)
{
    return ((struct Student*)e2)->score - ((struct Student*)e1)->score;
}
int main()
{
    struct Student stud[100];
    int n = 0, i = 0;
    scanf("%d", &n);
    for (i = 0; i < n; i++)
        scanf("%d%s%d", &stud[i].a, &stud[i].name, &stud[i].score);
    qsort(stud, n, sizeof(stud[0]), compare);
    for (i = 0; i < n; i++)
        printf("%d %s %d\n", stud[i].a, stud[i].name, stud[i].score);
    return 0;
}

排序的代码只有四行,是不是很简便呢,只要记住格式便可以使用了,多说无用,熟能生巧,快去练习吧。


int compare(const void* e1, const void* e2)
{
    return ((struct Student*)e2)->score - ((struct Student*)e1)->score;
}

qsort(stud, n, sizeof(stud[0]), compare);
   
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值