文章目录
1.qsort函数详解
作为C语言无理快排函数,学到就是赚到,啦啦啦~
1.1void*用法的引入
1.可以存放任意类型地址(指针)
2.无法进行解引用操作和指针运算。(不知道访问几个字节。)
1.2函数定义
void qsort
(
void* base, 待排数据首对象地址
size_t num, 排序数据元素个数
size_t size, 排序数据中一个元素大小,单位字节
int (*cmp) (const void*, const void*) 指向一个比较函数的指针(自定义)
);
1.3各类数据的cmp函数
int型
int cmp_int(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
float型
int cmp_float(const void* e1,const void* e2)
{
return (int)(*(float*)e1 - *(float*)e2);
}
字符串大小
int cmp_str_size(const void* e1, const void* e2)
{
return strcmp((char*)e1, (char*)e2);
}
字符串长度
int cmp_str_1en(const void* e1,const void* e2)
{
return strlen((char*)e1) - strlen((char*)e2);
}
注意:
1.cmp函数的返回值:> 0 (进行置换) <= 0 (不进行置换)
2.返回结果 :确保整形,若不是,则强制类型转换成整形!
1.4qsort函数应用
typedef struct Stu
{
char name[20];
int age;
}S;
void print_arr(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ",arr[i]);
printf("\n");
}
}
int sort_by_age(const void* a, const void* b)
{
return ( ( (S*)a )->age - ( ( (S*)b) ) ->age);
}
int sort_by_name(const void* a, const void* b)
{
return strcmp(((S*)a)->name, ((S*)b)->name);
}
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
S s[3] = { {"zhangsan", 30}, {"lisi", 34}, {"wangwu", 20} };
int sz_a = sizeof(a) / sizeof(a[0]);
int sz_s = sizeof(s) / sizeof(s[0]);
//qsort(a, sz_a, sizeof(a[0]), cmp_int); //整形数组排序
//qsort(s, sz_s,sizeof(s[0]), sort_by_age); //按年龄排序
//qsort(s, sz_s, sizeof(s[0]), sort_by_name);//按名字排序
//print_arr(a, sz_a);
return 0;
}
2.模仿qsort实现通用冒泡排序
1.1法一:充分利用内存函数
int cmp(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
void my_qsort(void* A, size_t n, size_t m, int(*cmp)(const void*, const void*))
{ //a 10 4
char* a = (char*)A;
char t[16];
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
//此语句功能:交换所比较的两个数字
if (cmp(a + j * m, a + (j + 1) * m))
{
memcpy(t, a + j * m, m);
memcpy(a + j * m, a + (j + 1) * m, m);
memcpy(a + (j + 1) * m, t, m);
}
}
}
}
int main()
{
int a[10] = { 9,8,7,6,5,4,3,2,1,0 };
my_qsort(a, 10, 4, cmp);
for (int i = 0; i < 10; i++)
printf("%d ", a[i]);
return 0;
}
1.2法二:充分体验库函数底层原理
int cmp_int(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
void print_arr(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
printf("\n");
}
}
void Swap(char* a, char* b, int width)
{
for (int i = 0; i < width; i++)
{
char t = *a;
*a = *b;
*b = t;
a++;
b++;
}
}
void bubble_sort
(
void* base,
int sz,
int width,
int (*cmp) (const void* e1, const void* e2)
)
{
for (int i = 0; i < sz - 1; i++)
{
for (int j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) )
Swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
}
}
}
int main()
{
int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]),cmp_int);
print_arr(arr, sz);
return 0;
}
3.使用指针实现bubble
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#define N 10
void ptr_sort(int* ptr, int n)
{
int t = 0;
for (int i = 1; i < n; i++)
{
for (int* p = ptr; p < ptr + n - i; p++)
{
if (*p > *(p + 1))
{
t = *p;
*p = *(p + 1);
*(p + 1) = t;
}
}
}
}
int main()
{
int a[N] = { 9,0,6,1,8,3,7,5,2,4};
ptr_sort(a, N);
for (int i = 0; i < N; i++)
{
printf("%d ", *(a + i));
}
return 0;
}