快速排序,作为能唯一能存在于库函数里的排序算法,qsort()的优势就在于非常灵活.
用man qsort 查看其文档
void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *));
发现它的优势就提现在他的参数用 使用了 void * 和函数指针.
参数: 1 待排序
数组首地址
2 数组中待排序元素数量
3 各元素的占用空间大小
4 指向函数的
指针,用于确定排序的顺序
那么接下来怎么自己实现qsort函数的实现呢 .
先看下快速排序的基本算法:
C语言版本:
voidQuickSort(int a[],int numsize)//a是整形数组,numsize是元素个数
{
int i=0,j=numsize-1;
int val=a[0];//指定参考值val大小
if(numsize>1)//确保数组长度至少为2,否则无需排序
{
while(i<j)//循环结束条件
{
for(;j>i;j--)//从后向前搜索比val小的元素,找到后填到a[i]中并跳出循环
if(a[j]<val)
{
a[i]=a[j];
break;
}
for(;i<j;i++)//从前往后搜索比val大的元素,找到后填到a[j]中并跳出循环
if(a[i]>val)
{
a[j]=a[i];
break;
}
}
a[i]=val;//将保存在val中的数放到a[i]中
QuickSort(a,i);//递归,对前i个数排序
QuickSort(a+i+1,numsize-1-i);//对i+1到numsize这numsize-1-i个数排序
}
}
对之改造后:
static void my_swap (char *a, char *b, size_t width)
{
if ( a != b )
while ( width-- ) {
*a++ = *b++;
}
}
void my_qsort(void *base,size_t numsize, size_t size, int (*comper)(const void *a, const void *b))
{
int i=0,j=numsize-1;
char val[size];
my_swap(val,(char *)base,size);
if(numsize>1)
{
while(i<j)
{
for(;j>i;j--)
if(comper((char *)base+j*size,val) < 0)
{
my_swap((char *)base+i*size, (char *)base+j*size, size);
break;
}
for(;i<j;i++)
if(comper((char *)base+i*size,val) > 0)
{
my_swap((char *)base+j*size, (char *)base+i*size, size);
break;
}
}
my_swap(((char *)base+i*size),val,size);
my_qsort(base, i, size, comper);
my_qsort(((char *)base+(i+1)*size), numsize-1-i, size, comper);
}
}
注意 在调用函数时 comper所指向的对比函数是要自己实现的 ,例如下面int类型的对比函数:
int cmpint(const void *a, const void *b)
{
return *(const int*)a-*(const int*)b;
}