简单的冒牌排序只能对一中数组的类型进行排序,现在我们用冒泡排序为基础来改造出一个可以对任意数组排序的排序函数!
后面附有实现的源码!
首先我们以qsort函数为例慢慢分析,然后确定我们的排序函数如何增强,第一步我们从它的参数下手,它一共4个参数。
1.第一个参数类型是void*,qsort函数可以用来对任意类型的数组排序,用void
*型指针可以直接接收各种类型的数组。
2.int num是数组的个数,
3.int width是指针的步长,后面我会进行解释.
4.int (*)(const void* e1,const void* e2)传递一个函数指针,比较函数,为什么是比较函数呢,我们要编写一个可以对任意类型的数组进行排序的函数,我们作为设计者,本身是不知道用户要用来排序那种类型的数组,所以让用户来传入一个他想排序数组的类型的比较函数,就可以按照用户的意愿来排序数组。
一、补充一下关于void*指针的知识,易于我们对下列函数实现的理解
void 类型的指针特点
void* 是一种无类型的指针,无具体类型的指针。
void* 的指针变量可以存放任意类型的地址 void* 的指针不能直接进行解引用操作。
void* 的指针不能直接进行+、-整数。
二、实现排序函数中的核心,比较函数
下面是qsort函数对比较函数的要求:
关于qsort函数,他要求比较函数的传入参数中的函数指针的比较函数的返回要求,返回值是一个int型,当e1小于e2时返回一个小于0的数,当e1大于e2时返回一个大于0的数,两者相等返回0;
我们也可以通过这里来改变,排序的升降序!!!
按照要求我们以简单的整形为例设计一个比较整形大小的函数:
1.比较int型大小的函数
2.比较float型大小的函数
3.比较结构题中字符串大小的函数
三、实现排序函数
这里我们是以冒泡排序为基础,来实现对各种数组的排序
1.冒泡排序的原型
2.对冒泡排序的核心进行升级
我们设计的排序中的核心便是使用用户传入的比较函数来判断两个数组元素的大小.这里就用到为啥要传入排序数组的步长了。
我们并不知道用户要排序的数组类型,所以我们并不能以int*或float*来直接接收数组元素,单数我们在知道数组元素的类型的步长之后,通过j*whdth来移动到下一个元素,再有用户传入的比较函数来比较大小。这点非常的巧妙!!!
四、转换函数的实现
同样我们不知道,排序数组的类型,但是我们通过一个字节一个字节的转换同样可以达到交换元素值的效果。
下面是附带的源码
#include#include #include //实现q_sort函数用冒泡排序 //只能排序整型 //void bubbling_sort(int *arr, int se) //{ // int i = 0; // int j = 0; // for (i = 0; i < se - 1; i++) // { // for (j = 0; j < se - 1 - i; j++) // { // //升序排列 // if (arr[j] > arr[j + 1]) // { // int tem = arr[j]; // arr[j] = arr[j + 1]; // arr[j + 1] = tem; // } // } // } //} struct Stu { char name[20]; int age; float score; }; //打印排序后结果 void print_arr_int(int* arr, int se) { int i = 0; for (i = 0; i < se ; i++) { printf("%d ", *(arr + i)); } } void print_arr_float(float* arr, int se) { int i = 0; for (i = 0; i < se; i++) { printf("%.2f ", *(arr + i)); } } void printf_stu(struct Stu arr[], int se) { int i = 0; for (i = 0; i < se; i++) { printf("%s %d %.2f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void swap(char *num1, char *num2, int width) { int i = 0; for (i = 0; i < width; i++) { char tem = *num1; *num1 = *num2; *num2 = tem; num1++; num2++; } } void my_sort(void *arr, int se, int width, int (*comp)(const void* e1, const void* e2)) { int i = 0; int j = 0; for (i = 0; i < se - 1; i++) { for (j = 0; j < se - 1 - i; j++) { //升序排列 if (comp((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0) { //交换数组元素 swap((char*)arr + j * width, (char*)arr + (j + 1) * width, width); } } } } int comp_int(const void* e1,const void* e2) { return (*(int*)e1)-(*(int*)e2); } int comp_float(const void* e1, const void* e2) { if ((*(float*)e1) - (*(float*)e2) > 0) { return 1; } else if ((*(float*)e1) - (*(float*)e2) < 0) { return -1; } else { return 0; } } int comp_stu_name(const void* e1, const void* e2) { return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); } int main() { int arr[] = {9,8,7,6,5,4,3,2,1,0}; //float arr[] = { 9.1f, 5.1f, 45.0f, 1.2f, 11.3f }; //struct Stu arr[] = { {"zhangsan",18,99.2f},{"lisi",28,78.2f},{"wangwu",12,60.5f}}; int se = sizeof(arr) / sizeof(arr[0]); my_sort(arr, se, sizeof(arr[0]), comp_int); //my_sort(arr, se, sizeof(arr[0]), comp_float); //my_sort(arr, se, sizeof(arr[0]), comp_stu_name); print_arr_int(arr,se); //print_arr_float(arr,se); //printf_stu(arr, se); return 0; }
总结
到此这篇关于C语言对冒泡排序进行升级介绍的文章就介绍到这了,更多相关C语言冒泡排序升级内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!