目录
前言:
上一次小编和大家分享了指针进阶的一些知识,那么这次小编就和大家一起来结合指针一起来学习一下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函数,希望对大家有所帮助,下次小编将会给大家分享指针的一些具体练习,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)