一.qsort函数的类型及参数
void qsort(void *base,size_t num,size_t width,int (*compare)(const void* elem1),const void* elem2)
1.第一个参数base:待排序数组的首元素的地址,数据类型为void*。
2.第二个参数 num:待排序数组的元素个数,数据类型为size_t(unsigned int)。
3.第三个参数width:待排序数组的每个元素的字节大小,数据类型为size_t。
4.第四个参数compare:一个函数指针,函数功能为:比较数组中的两个元素。(需要自己实现)。函数的参数有两个,类型为const void* ,分别为待比较的两个元素的地址。
二.qsort函数的应用
1.利用qsort函数对整型数组排序
#include <stdio.h>
int compare(const void* elem1,const void* elem2)
{return *(int*)elem1-*(int*)elem2;
}
int main()
{ int i=0;int a[10]={2,1,3,5,6,4,8,7,9,0};int sz=sizeof(a)/sizeof(a[0]);qsort(a,sz,sizeof(a[0]),compare);for(i=0;i<sz;i++){printf("%d ",a[i]);}return 0;
}
运行结果:
2.利用qsort函数对字符数组排序
#include <stdio.h>
int compare(const void* elem1,const void* elem2)
{return *(char*)elem1-*(char*)elem2;
}
int main()
{ int i=0;char c[10]={'n','m','d','i','t','b','c','a','g','f'};int sz=sizeof(c)/sizeof(c[0]);qsort(c,sz,sizeof(c[0]),compare);for(i=0;i<sz;i++){printf("%c ",c[i]);}return 0;
}
运行结果:
三.模拟实现qsort函数(冒泡排序)
void swap(char* buf1, char* buf2,int n)//交换两个元素
{int i;for (i = 0; i < n; i++){char temp=*buf1;*buf1 = *buf2;*buf2 = temp;buf1++;buf2++;}
}
//利用冒泡排序实现
void bubble_sort(void* base, size_t sz, size_t width, int(*cmp)(const void* elem1,const void* elem2))
{int i = 0;int j = 0;for (i = 0; i < sz-1; i++){for (j = 0; j < sz - 1 - i; j++){if (cmp((char*)base + j*width, (char*)base + (j + 1)*width)>0)//(char*)base + j*width为第一个元素,(char*)base + (j + 1)*width为下一个元素swap((char*)base + j*width, (char*)base + (j + 1)*width, width);}}
}
测试
用上述代码对结构体数组排序
#include <string.h>
#include <stdio.h>
struct Stu
{char name[20];int age;
};
//通过姓名比较
int cmp_by_name(const void *elem1, const void *elem2)
{return strcmp(((struct Stu*)elem1)->name,((struct Stu*)elem2)->name);
}
//通过年龄比较
int cmp_by_age(const void *elem1, const void *elem2)
{return ((struct Stu*)elem1)->age,((struct Stu*)elem2)->age;
}
void swap(char*buf1, char*buf2,int n)
{int i;for (i = 0; i < n; i++){char temp=*buf1;*buf1 = *buf2;*buf2 = temp;buf1++;buf2++;}
}
void bubble_sort(void* base, int sz, int width, int(*cmp)(const void* elem1,const void* elem2))
{int i = 0;int j = 0;for (i = 0; i < sz-1; i++){for (j = 0; j < sz - 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);}}
}
int main()
{struct Stu s[3] = { { "zhangsan", 10 }, { "aishi", 20 }, { "wangwu", 30 } };int sz = sizeof(s) / sizeof(s[0]);bubble_sort(s, sz, sizeof(s[0]),cmp_by_name);for (int i = 0; i < sz; i++){printf("%s ", (s+i)->name);}return 0;
}
运行结果:
总结
传统的冒泡排序只能对单一数据类型的数组进行排序,如果要对另一数据类型的数组进行排序,就要重新写一个冒泡排序,这难免有些复杂。而qsort利用char数据类型只占用一个字节的特点,其他数据类型都可用此表示(例如上面代码中的(char*)base + j*width),将传入的参数用void*类型的指针接收,再将其强制转换成原数据类型,就可解决传统冒泡排序解决不了的问题。
(附:第一次发表博客,请多多包涵,如有错误的地方,欢迎指正,感谢您的阅读)