目录
一、qsort() 介绍
qsort()
就是C语言中的快排函数,包含在 stdlib.h
头文件中;
函数一共有四个参数,没有返回值。
int cmp(const void *a, const void *b) {
// 代码体
}
qsort(arr, n, sizeof(arr[0]), cmp);
1、第一个参数 s
是一个地址,即参与排序的首地址
;
2、n
是需要排序的数量;
3、sizeof(s[0])
则是每一个元素占用的空间大小
;
4、指向函数的指针,用于确定排序的顺序。
1.1 字符串数组的排序:char *s[]型
C代码1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
// return (strcmp(*(char **)a, *(char **)b));
return (strcmp((char *)a, (char *)b)); // 效果一致
}
void change1(char *a)
{
printf("%p\n", a);
a[0] = 'y';
}
void change2(char **a) // 要求入参必须传 "指针的地址" &s[0]、&arr,不然编译器报错
{
printf("%p\n", a);
printf("%p\n", *a);
(*a)[0] = 'z';
}
int main()
{
char str1[] = "java";
char str2[] = "python";
char str3[] = "ssdsfbdbd";
char **s;
s = (char **)malloc(sizeof(char *) * 2);
s[0] = (char *)malloc(sizeof(char *));
s[0] = str1;
s[1] = (char *)malloc(sizeof(char *));
s[1] = str2;
change1(s[0]);
change2(&s[0]); //
qsort(s, 2, sizeof(s[0]), cmp);
for (int i = 0; i < 2; i++) {
printf("%s\n", s[i]);
}
return 0;
}
000000000061FDFB
0000000000181570
000000000061FDFB
python
zava
————
C代码2:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
// return (strcmp(*(char **)a, *(char **)b));
return (strcmp((char *)a, (char *)b)); // 一致
}
int main()
{
char *arr[100]; // 此处已经开辟了 100个空间内存
int i, n;
scanf("%d", &n);
for (i = 0; i < n; i++) {
arr[i] = (char *)malloc(sizeof(char *)); // 不应该是 arr[i] = (char *)malloc(sizeof(char) * len)吗?
scanf("%s", arr[i]);
}
qsort(arr, n, sizeof(arr[0]), cmp);
for (i = 0; i < n; i++) {
printf("%s\n", arr[i]);
}
return 0;
}
1.1.1 (char *)malloc(sizeof(char) * len) 强制转换为8个字节(64位系统))
char *arr[5];
arr[0] = (char *)malloc(sizeof(char) * 1);
printf("%d\n", sizeof(arr[0])); // 8
arr[1] = (char *)malloc(sizeof(char) * 10);
printf("%d\n", sizeof(arr[1])); // 8
arr[2] = (char *)malloc(sizeof(char) * 100);
printf("%d\n", sizeof(arr[2])); // 8
arr[3] = (char *)malloc(sizeof(char) * 1000);
printf("%d\n", sizeof(arr[3])); // 8
arr[4] = (char *)malloc(0); // (char *) 会强制转换为 char* 的内存大小(8个字节)
printf("%d\n", sizeof(arr[4])); // 8
1.1.2 sizeof() 用法
int arr2[10];
char arr3[10]= "c";
char *arr[10]; // 指针数组(存放指针的数组)
char *p = "hello";
int *arr4;
printf("%d\n", sizeof(arr2)); // 40个字节:一个int类型占4个字节(32位)(32/64位系统)
printf("%d\n", sizeof(arr3)); // 10个字节:一个字符占1个字节 (32/64位系统)
printf("%d\n", sizeof(arr)); // 80个字节:一个char* 指针占8个字节(64位)(32:4、64:8)
printf("%d\n", sizeof(char)); // 1个字节(8 bit)
printf("%d\n", sizeof(char*)); // 8个字节
printf("%d\n", sizeof(p)); // 8个字节
printf("%d\n", sizeof(arr4)); // 8个字节
arr4 = arr2; // arr4 就是一个地址了
printf("%d\n", sizeof(arr4)); // 8个字节
// 【指针变量】的所占空间大小仅仅和操作系统位数有关32-4,64-8
printf("%d\n", sizeof(unsigned short)); // 2字节
printf("%d\n", sizeof(signed short)); // 2字节
printf("%d\n", sizeof(unsigned char)); // 1字节
printf("%d\n", sizeof(signed char)); // 1字节
printf("%d\n", sizeof(unsigned int)); // 4字节
printf("%d\n", sizeof(signed int)); // 4字节
printf("%d\n", sizeof(unsigned long)); // 4字节
printf("%d\n", sizeof(signed long)); // 4字节
printf("%d\n", sizeof(unsigned long long)); // 8字节
printf("%d\n", sizeof(signed long long)); // 8字节
printf("%d\n", sizeof(float)); // 4字节
printf("%d\n", sizeof(double)); // 8字节
1.2 字符串数组的排序:char s[][]型
C代码1:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
return (strcmp((char *)a, (char *)b)); // strcmp接收地址
}
int main()
{
char s[100][100]; // 内存均已申请
int i, n;
scanf("%d", &n);
for (i = 0; i < n; i++) {
printf("s[i] len = %d\n", strlen(s[i]));
scanf("%s", s[i]); // 此时不用再申请字符串的长度内存了,已申请长度100的字符串内存大小
printf("s[i] len1 = %d\n", strlen(s[i]));
}
qsort(s, n, sizeof(s[0]), cmp);
for (i = 0; i < n; i++) {
printf("%s\n", s[i]);
}
return 0;
}
测试代码:
s[i] len = 0
fsfs
s[i] len1 = 4
s[i] len = 0
wfefefg
s[i] len1 = 7
s[i] len = 0
hrhr
s[i] len1 = 4
fsfs
hrhr
wfefefg
————
C代码2:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
return (strcmp((char *)a, (char *)b));
}
int main()
{
/*
1、创建了5个长度为10的一维数组
2、一维数组、二维数组的内存均已创建,为静态内存;
3、内存为10、字符串未填满,后面的内存存放'\0',解析为NULL
*/
char s[5][10] = {"asc", "asdf", "fggvd"};
qsort(s, 3, sizeof(s[0]), cmp);
for (int i = 0; i < 3; i++) {
printf("%s\n", s[i]);
}
return 0;
}
1.3 struct型
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int key;
double val;
} Node;
void change1(Node* a) {
a->key = 11111;
}
// void change2(Node a) { // 编译会报错,必须用指针!
// a.key = 222222;
// }
int cmp(const void* _a, const void* _b)
{
Node *a = (Node *)_a;
Node *b = (Node *)_b;
if (a->val != b->val) { // aa->val 与 (*aa).val 等效
return (a->val > b->val) ? 1 : -1; // 按值升序
} else {
return a->key - b->key; // key为序号,如此保持原顺序
}
}
int main()
{
// Node arr[10];
// int n;
// scanf("%d", &n);
// for (int i = 0; i < n; i++)
// {
// arr[i].key = i + 1; // Node arr[10] 创建的数组,与 char *arr[10]数组不一样,后者需要创建指针的8字节内存
// scanf("%lf", &arr[i].val);
// }
// qsort(arr, n, sizeof(arr[0]), cmp);
Node arr[10] = {
{1, 10.1},
{2, 3.4},
{3, 3.4},
{4, 6.666}
};
change1(arr);
// change2(arr + 1);
// printf("%d\n", sizeof(arr)); // 160个字节
// printf("%d\n", sizeof(arr[0])); // 16个字节
qsort(arr, 4, sizeof(arr[0]), cmp);
for (int i = 0; i < 4; i++)
printf("%d %lf\n", arr[i].key, arr[i].val);
return (0);
}
1.4 int型数组
C代码1:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
return (*(int *)a - *(int *)b);
}
int main()
{
int arr[10000], n, i;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
qsort(arr, n, sizeof(arr[0]), cmp);
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
测试输出:
PS D:\CODE\test2> & 'c:\Users\Steve_long\.vscode\extensions\ms-vscode......
3
4
5
1
1 4 5
C代码2:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
return (*(int *)b - *(int *)a); // 降序
}
int main()
{
int n = 3;
int arr[3] = {1, 2, 3};
qsort(arr, n, sizeof(arr[0]), cmp);
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
return 0;
}
1.4 char型数组
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
return (*(char *)a - *(char *)b); // (char *)a 类似接口形参:const char *a;
} // 指针接收
int main()
{
// char s[10];
// scanf("%s", s);
char s[20] = "sfsfsdfgaaasa";
printf("%d\n", sizeof(s[0])); // 1个字节
qsort(s, strlen(s), sizeof(s[0]), cmp); // aaaadfffgssss
printf("%s", s);
return (0);
}
1.5 double型数组
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *a, const void *b)
{
return ((*(double *)a - *(double *)b > 0) ? 1 : -1); // double类型做减法不一定是整数,所以返回 1、-1
}
int main()
{
double s[1000];
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%lf", &s[i]);
qsort(s, n, sizeof(s[0]), cmp);
for (int i = 0; i < n; i++)
printf("%lf ", s[i]);
return 0;
}