C语言之快速排序及qsort()

一、快速排序

算法思想:基于分治的思想,首先在数组中选择一个基准点,然后分别从数组的两端扫描数组,设两个指示标志(low指向起始位置,high指向末尾),从后半部分开始,如果发现有元素比该基准点的值小,就交换low和high位置的值,然后从前半部分开始扫秒,发现有元素大于基准点的值,就交换low和high位置的值,如此往复循环,直到low>=high,然后把基准点的值放到high这个位置。一次排序就完成了。以后采用递归的方式分别对前半部分和后半部分排序,当前半部分和后半部分均有序时该数组就自然有序了。

快速排序c代码实现如下:

  #include<stdio.h>
    #define MAX_SIZE 6
    int findPos(int *a, int low, int high)
    {
	    int val = a[low];							//默认a[low]为基准
	    while(low < high)
	    {
		    while(low < high && a[high] >= val)		//右边第一个小于基准的数
			    high--;
		    a[low] = a[high];
		    while(low < high && a[low] <= val)		//左边第一个大于基准的数
			    low++;
		    a[high] = a[low];
	    }
	    a[low] = val;
	    return low;
    }
    void quickSort(int *a, int low, int high)
    {
	    int pos;
	    if(low < high)
	    {
		    //找到基准位置的索引
		    pos = findPos(a, low, high);
		    //对基准两边递归调用快速排序
		    quickSort(a, low, pos-1);
		    quickSort(a, pos+1, high);
	    }
    }
    int main()
    {
	    int i, array[MAX_SIZE];
	    for(i = 0;i < MAX_SIZE; i++)
		    scanf("%d", &array[i]);
	    quickSort(array, 0, MAX_SIZE-1);
	    for(i = 0;i < MAX_SIZE; i++)
		    printf("%d ", array[i]);
	    printf("\n");
	    return 0;
    }

二、qsort()函数

快速排序可以借助C语言编译器函数库自带的快速排序函数qsort( ),函数原型为:

    #include<stdlib.h>

    void qsort(void*base,size_t num,size_t width,int(__cdecl*compare)(const void*,const void*));

参数依次为:

  • 待排序数组首地址:即数组名或指向数组的指针;
  • 数组长度:size_t是标准C库中定义的unsigned int,输入待排序的数组的长度;
  • 数组元素所占字节:直接用sizeof(a[0])计算字数组单个元素的节数;
  • 所调用函数的指针,函数名即是函数的指针,可直接写函数名,调用函数用来确定排序的方式。

qsort要求提供一个自定义的比较函数,返回值为int。比较函数使得qsort通用性更好,有了比较函数qsort可以实现对数组、字符串、结构体等结构进行升序或降序排序。

    //自定义cmp函数参数固定
    //int 整型
    int cmp_int(const void *a,const void *b)
    {
        return *(int *)a - *(int *)b;
    }

    //double 浮点型
    int cmp_double(const void *a,const void *b)
    {
         return *(double*)a>*(double*)b? 1 : -1;
    }
    注: 这里两个浮点数相减但要返回一个整型数,如果按上面做法直接减会丢失小数点部分。

    //char 字符型或字符串首字母
    int cmp_char(const void *a,const void *b)
    {
        return *(char*)a-*(char*)b;
    }
        
    //字符串长度
    int cmp_str(const void *a,const void *b)
    {
       return strlen((char*)a)-strlen((char*)b);
    }
        
    
    //字符串字典顺序
    int cmp_str(const void *a, const void *b)
    {
        return (strcmp((char *)a, (char *)b));
    }
     
    //结构体排序
    struct student{
        int num;
        char ch;
    }stu[10];
    int cmp_stu(const void *a,const void *b)
    {
        if((* (student* )a).num != ( * (student * )b).num)
            return (*(student *)a).num - (*(student *)b).num;
        else return (*(student *)a).ch - (*(student *)b).ch;
    }

注意:strlen返回类型为size_t,应为unsigned int,在64位系统中为 long unsigned int。无符号整型最好不要做四则运算。这里虽然函数返回int型,会把无符号数转换为整型,但返回结果只在字符串的长度未超过int的范围时正确。这种大范围转小范围要考虑精度损失的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值