详细讲解C语言16(C语言系列)

目录

前言:

冒泡排序:

qsort函数的介绍: 

qsort函数排序整形数据:

qsort函数排序结构体数据: 

用冒泡排序来模拟实现qsort函数:

整形:

结构体:

结束语:


前言:

上一次小编和大家分享了指针进阶的一些知识,那么这次小编就和大家一起来结合指针一起来学习一下qsort这个函数吧!

冒泡排序:

首先在学习qsort这个函数之前我们先来回顾一下我们之前学习过的冒泡排序吧!

思想解析:

 代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
//升序
void bubble_sort(int arr[], int s)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < s; i++)
	{
		for (j = 0; j < s - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}


代码运行结果:

qsort函数的介绍: 

qsort是C语言标准库提供的排序函数,可以排序任意类型的数据,它的底层思想是快速排序。

头文件:#include<stdlib.h>

qsort函数的使用方法:

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

下面对qsort函数的参数进行具体的详解:
 

解释为什么要使用void来作为指针类型?

因为void*指针是非常宽容的,它可以接收任意类型的地址。

如下所示:
char ch = 'W';

int i = 0;

void* p = &ch;

void* p = &i;

但是使用的时候有两个限制:
1.不可直接对它进行解引用操作。如:(*p)= 200;(错误

2.不可对它进行+ - 1操作。如:p++、p--(错误) 

注意:如果要使用则应该在使用前进行类型转换。如:*(int*)p = 200; 

int (*cmper)(const void* p1, const void* p2)是如何进行比较的?

return value两元素的大小
>0* p1 > * p2
=0* p1 = * p2
<0* p1 < * p2

在比较的时候:
2个整形使用关系运算符比较大小。

2个字符串,使用strcmp函数比较大小。

2个结构体得制定特定的比较方式,具体见下面的代码所示。 


qsort函数排序整形数据:

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#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 -1;
	else
		return 0;
}
//改进:
//int  cmp_int(const void *e1,const void *e2)
//{
//	return (*(int*)e1 - *(int*)e2);
//}
int main()
{
	int arr[10] = { 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;
}


代码运行结果:

qsort函数排序结构体数据: 

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct stu
{
	char name[20];
	int age;
};
int cmp_stu_by_name(const void* p1, const void* p2)
{
	return (strcmp((*(struct stu*)p1).name, (*(struct stu*)p2).name));
}
int cmp_stu_by_age(const void* p1, const void* p2)
{
	return ((*(struct stu*)p1).age - (*(struct stu*)p2).age);
}
int main()
{
	struct stu s[3] = { {"zhangsan",20},{"wangwu",19},{"lisi",22} };
	int sz = sizeof(s) / sizeof(s[0]);
	//使用姓名进行排序
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%s %d", s[i].name, s[i].age);
		printf("\n");
	}
	//使用年龄进行排序
	printf("\n");
	qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
	for (i = 0; i < sz; i++)
	{
		printf("%s %d", s[i].name, s[i].age);
		printf("\n");
	}
	return 0;
}


代码运行结果:

用冒泡排序来模拟实现qsort函数:

整形:

代码展示:

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
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++;
	}
}
void bubble_sort(void* base, int s, int width, int (*cmp_int)(const void* p1, const void* p2))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < s; i++)
	{
		for (j = 0; j < s - 1 - i; j++)
		{
			if(cmp_int((char*)base + j * width , (char*)base + (j + 1) * width) > 0)
				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);//交换
		}
	}
}
int cmp_int(const void* p1, const void* p2)
{
	return (*(char*)p1 - *(char*)p2);
}
int main()
{
	int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}


代码运行截图:

结构体:

代码展示:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

struct stu
{
	char name[20];
	int age;
};
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++;
	}
}
int cmp_stu_name(const void* p1, const void* p2)
{
	return (strcmp((*(struct stu*)p1).name, (*(struct stu*)p2).name));
}
int cmp_stu_age(const void* p1, const void* p2)
{
	return ((*(struct stu*)p1).age - (*(struct stu*)p2).age);
}
void bubble_sort1(void* base, int s, int width, int (*cmp_int)(const void* p1, const void* p2))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < s; i++)
	{
		for (j = 0; j < s - 1 - i; j++)
		{
			if (cmp_stu_name((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);//交换
		}
	}
}

void bubble_sort2(void* base, int s, int width, int (*cmp_int)(const void* p1, const void* p2))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < s; i++)
	{
		for (j = 0; j < s - 1 - i; j++)
		{
			if (cmp_stu_age((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);//交换
		}
	}
}

int main()
{
	struct stu s[3] = { {"zhangsan",20},{"wangwu",19},{"lisi",22} };
	int sz = sizeof(s) / sizeof(s[0]);
	//使用姓名进行排序
	bubble_sort1(s, sz, sizeof(s[0]), cmp_stu_name);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%s %d", s[i].name, s[i].age);
		printf("\n");
	}
	printf("\n");
	//使用年龄进行排序
	bubble_sort2(s, sz, sizeof(s[0]), cmp_stu_age);
	for (i = 0; i < sz; i++)
	{
		printf("%s %d", s[i].name, s[i].age);
		printf("\n");
	}
	return 0;
}


代码运行结果:

结束语:

这次小编与大家分享了qsort函数的具体使用方法,以及用冒泡排序来模拟实现qsort函数,希望对大家有所帮助,下次小编将会给大家分享指针的一些具体练习,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力敲代码的小白✧٩(ˊωˋ*)و✧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值