目录
26.自制排序函数(★★)
*分析
*代码
往期推荐
26.自制排序函数
*分析
之前在42.【C语言】冒泡排序写过一个排序函数,可以将此自制一个类似qsort的函数
画圈的地方是需要修改的
#include <stddef.h>
void bubble_sort(void* base, size_t num,size_t width,int (*cmp)(const void*p1,const void*p2))
解释参数:
和qsort函数一样,
> base指针存放第一个元素的地址,由于不知道元素是什么类型,因此写void*
> num,width一定是unsigned类型,用size_t
> width 为一个元素所占的字节数,好让计算机知道元素的排布方式
> p1和p2为需要比较的两个元素,由于不知道元素是什么类型,因此写void*,又要确保稳定,用const修饰
> 比较完p1和p2后,要返回值,因此用int
下方图片摘自cplusplus网 点我跳转
大致的框架
void bubble_sort(void* base, size_t num, size_t width, int (*cmp)(const void* el, const void* e2))
{
for (size_t i = 0; i < num - 1; i++)
{
for (size_t j = 0; j < num - 1 - i; j++)
{
//if判断元素
//满足一定条件则交换,否则无动作
}
}
}
注:为保证i,j与width类型相同,写成size_t i = 0; size_t j = 0;
详解if判断元素的写法 :
if (调用cmp函数) --> if (cmp()) --> if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) //由于数组的元素是连续排列的,因此需要知道每个元素具体占多少字节来访问每个元素,可以在base的基础上+j*width来移动,因此base是void*型,要强制类型转换为char*,才可一次只跳过一个字节 --写元素交换代码-->告诉两个元素的起始地址和交换的宽度-->swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
*代码(一次一个字节交换)
void swap(char* p1, char* p2, size_t width)
{
for (size_t i = 0; i < width; i++)
{
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2++;
}
}
元素1位置=base+j*width 元素2位置=base+(j+1)*width
完整代码:
#include <stddef.h>
#include <stdio.h>
void print_arr(int arr[ ], int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int cmp_int(const void* p1, const void* p2)
{
return *(int*)p1 - *(int*)p2; //由小到大排序
}
void swap(char* p1, char* p2, size_t width)
{
for (size_t i = 0; i < width; i++)
{
char tmp = *p1;
*p1 = *p2;
*p2 = tmp;
p1++;
p2++;
}
}
void bubble_sort(void* base, size_t num, size_t width, int (*cmp)(const void* el, const void* e2))
{
for (size_t i = 0; i < num - 1; i++)
{
for (size_t j = 0; j < num - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
void int_func()
{
int arr[10] = { 1,6,8,2,5,3,8,9,0,3 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
int main()
{
int_func();
return 0;
}
如果排序字符,只需要改动两处
int arr[10] = { 'a','c','r','1','@','q','m','+','!','3'};
printf("%c ", arr[i]);
查ASCII表知(显示十进制):
<<<<<<<<<
往期推荐:
19.【C语言】指针(重难点)(A)
37.【C语言】指针(重难点)(B)
38.【C语言】指针(重难点)(C)
39.【C语言】指针(重难点)(D)
40.【C语言】指针(重难点)(E)
43.【C语言】指针(重难点)(F)
44.【C语言】指针(重难点)(G)
45.【C语言】指针(重难点)(H)
46.【C语言】指针(重难点)(I)