当前位置: 代码迷 >> 综合 >> qsort()快速排序自主实现
  详细解决方案

qsort()快速排序自主实现

热度:97   发布时间:2023-12-06 11:00:41.0

目录

代码:

需要注意的一个地方:


经过一个上午,快速排序版的qosrt()的自主实现完成了!

建议先看我之前我的快速排序文章和上一篇文章(建议两个都看后再来看这个)我用的是我自己写的快速排序的方式,可能与其他人的不太相同。

快速排序:C语言快速排序算法_笨笨噠的博客-CSDN博客_快速排序算法c语言

上一篇文章冒泡排序实现qsort():qsort的自主实现_笨笨噠的博客-CSDN博客

代码:

void my_copy(char* dst, char* src, int len)
{int i = 0;for (i = 0; i < len; i++){*(dst + i) = *(src + i);}
}void q_fast_sort(void* base, int left, int right, size_t width, int (*p)(const void* e1, const void* e2))
{int t = right;char* flag = (char*)malloc(width);assert(flag);my_copy(flag, (char*)base + left * width, width);while (left < right){if (p((char*)base + right * width, flag) < 0){my_copy((char*)base + left * width, (char*)base + right * width, width);left++;while (left < right){if (p((char*)base + left * width, flag) > 0){my_copy((char*)base + right * width, (char*)base + left * width, width);right--;break;}else{left++;}}}else{right--;}}my_copy((char*)base + left * width, flag, width);if (left - 1 > 0){q_fast_sort(base, 0, left - 1, width, p);}if (right + 1 < t){q_fast_sort(base, right + 1, t, width, p);}free(flag);flag = NULL;
}void my_fast_sort(void* base, size_t num, size_t width, int (*p)(const void* e1, const void* e2))
{assert(base);//确保数组的有效性q_fast_sort(base, 0, num - 1, width, p);
}

这里注意flag是用来记录第一个元素的值,但是因为不知道传进来数组的元素是什么类型,所以我先在堆里面开辟一块一个元素的大小的空间,然后老样子,用转换char*进行赋值,所以我直接用char*来作为flag的类型。

需要注意的一个地方:

结构体的知识,这里一定要看!!!

我把结构体的代码放在这里,其他代码均用上一篇的测试数据测试(均正确

#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>typedef struct Student
{char name[10];double scores;
} Student;int compare4(const void* e1, const void* e2)
{return (int)(((Student*)e1)->scores - ((Student*)e2)->scores);
}void my_copy(char* dst, char* src, int len)
{int i = 0;for (i = 0; i < len; i++){*(dst + i) = *(src + i);}
}void q_fast_sort(void* base, int left, int right, size_t width, int (*p)(const void* e1, const void* e2))
{int t = right;char* flag = (char*)malloc(width);assert(flag);my_copy(flag, (char*)base + left * width, width);while (left < right){if (p((char*)base + right * width, flag) < 0){my_copy((char*)base + left * width, (char*)base + right * width, width);left++;while (left < right){if (p((char*)base + left * width, flag) > 0){my_copy((char*)base + right * width, (char*)base + left * width, width);right--;break;}else{left++;}}}else{right--;}}my_copy((char*)base + left * width, flag, width);if (left - 1 > 0){q_fast_sort(base, 0, left - 1, width, p);}if (right + 1 < t){q_fast_sort(base, right + 1, t, width, p);}free(flag);flag = NULL;
}void my_fast_sort(void* base, size_t num, size_t width, int (*p)(const void* e1, const void* e2))
{assert(base);//确保数组的有效性q_fast_sort(base, 0, num - 1, width, p);
}int main(void)
{Student s[5] = { {"张三", 10}, {"李四", 0}, {"王五", 100}, {"乌龟", 0.5}, {"兔子", -20} };int i = 0;int j = 0;for (i = 0; i < 5; i++){printf("%-6s%lf\n", s[i].name, s[i].scores);}printf("\n======================\n");int len4 = sizeof(s) / sizeof(s[0]);my_fast_sort(s, len4, sizeof(s[0]), compare4);for (i = 0; i < 5; i++){printf("%-6s%lf\n", s[i].name, s[i].scores);}return 0;
}

我把结构体的代码放在这里是有原因的,因为上一篇访问结构体成员的方式有人可能不太理解(我认为的),刚开始我也遇到问题了,我刚开始是这样访问的

(Student*)e1->scores

错误,大错特错,为什么?

因为操作符优先级问题,看一下我的操作符详解的那篇文章最后的优先级表(我上一篇文章忘记提醒了,写着写着就忘记提醒了)。

操作符详解:操作符详解_笨笨噠的博客-CSDN博客

 目录的最后有优先级表,建议有时间看完整篇文章(与操作符详解这篇文章之前的文章结合效果更好),也算对博主的支持了

->的优先级比强制类型转换的优先级高,所以刚才那样写先对空类型指针进行访问再强制类型转换,编译器不知道空类型指针到底占用多少内存,所以就报错了。

正确的引用

((Student*)e1)->scores

这是我自己测试的数据和结果:

 这是上一篇文章的数据测试结果:

 

 这些结果是我用刚写的代码测试的,不是昨天的测试结果(主要是不想凑文字,感觉还不如来点实的,效率才是重要的)。如果想测试这些篇文章的数据可找上一测试数据进行测试。

千辛万苦转到定义(下载插件),看后一脸懵