qsort库函数和函数指针

c语言快速排序库函数qsort:

在C语言的定义中,我们可以看到他的函数原型

void qsort( void * Base,int nelem, unsigned int width, in (* PfCompare)(const void , const void ));

此函数可对任意类型的数组进行排序

这个函数对数组排序时需要知道:

  1. .数组起始的地址
  2. 数组元素的个数
  3. 每个元素的大小
  4. 元素的排序规则

代码中每个单词的含义:
base:待排序数组地址的起始地址
nelem:待排序数组的元素个数
width:每个元素的大小
pfcompare:比较函数的地址(该比较函数需自己编写规则)

ps:pf函数形式:int 函数名(const void * elem1,const void* elem2)

排序就是一个不断比较并交换位置的过程。

qsort函数在执行期间,会通过pfcompare指针调用“比较函数”,
调用时将要比较的两个元素的地址传给“比较函数”,然后根据
“比较函数”返回值判断两个元素哪个更应该排在前面。

这里写图片描述

比较函数的编写规则:

  1. 如果*elem1应该排在*elem2前面,则函数返回值是负整数
  2. 如果*elem1和*elem2Negev排在前面都行,那么返回值0
  3. 如果*elem1应该排在*elem2垢面,则函数返回值是正整数

实例:
下面的程序,功能是调用qsort函数,将一个unsigned int数组按照个位数从小到大进行排序。比如8,23,15三个数,
按个位数从小到大排序,应该是23,15,8

#include<stdio.h>
#include<stdlib.h>
int mycompare(const void* elem1,const void* elem2)
{
    unsigned int* p1,*p2;
    p1=(unsigned int*)elem1;//"*elem1"非法
    p2=(unsigned int*)elem2;
    return (*p1%10)-(*p2%10);
}
#define NUM 5
int main()
{
    unsigned int a[NUM]={8,123,11,10,4};
    qsort(a,NUM,sizeof(unsigend int),mycompare);
    for(int i=0;i<NUM;i++)
        printf("%d",a[i]);
    return 0;
}

输出结果 10 11 123 4 8

如果自己写一个通用的快排函数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct S
{
    char name[10];
    float score;
}stu;
int cmp(const void*n1, const void*n2)
{
    return *(int*)n1 - *(int*)n2;
}
int struct_cmp(const void *elem1, const void *elem2)
{
    return (*(stu *)elem1).score - (*(stu *)elem2).score;
}
int str_cmp(const void *elem1, const void *elem2)
{
    return strcmp((char *)*(int *)elem1, (char *)*(int *)elem2);
}
void swap(char *buf1, char* buf2, int width)
{
    int i = 0;
    for (i = 0; i < width; i++)
    {
        char tmp = *buf1;
        *buf1 = *buf2;
        *buf2 = tmp;
        buf1++;
        buf2++;
    }
}
void bubble_sort(void *base, int len, int width, int(*cmp)(const void* n1, const void*n2))
{
    int i = 0;
    for (i = 0; i < len - 1; i++)
    {
        int j = 0;
        for (j = 0; j < len - 1 - i; j++)
        {
            int ret = cmp(((char*)base + (j*width)), ((char*)base + (j + 1)*width));
            if (ret>0)
            {
                swap(((char*)base + (j*width)), ((char*)base + (j + 1)*width), width);
            }
        }
    }
}
int main()
{
    int arr[] = { 8, 5, 6, 1, 2, 3, 4 };
    int len = sizeof(arr) / sizeof(arr[0]);
    bubble_sort(arr, len, sizeof(arr[0]), cmp);
    int i = 0;
    for (i = 0; i <len; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
    char arr1[] = { 'f', 'h', 'm', 'l', 'g', 'k', 'c' };
    int len1 = sizeof(arr1) / sizeof(arr1[0]);
    bubble_sort(arr1, len1, sizeof(arr1[0]), cmp);
    for (i = 0; i < len1; i++)
    {
        printf("%c ", arr1[i]);
    }
    printf("\n");
    stu arr2[] = { { "aa", 9}, { "bb", 6}, { "cc", 8}, { "dd", 7} };
    int len2 = sizeof(arr2) / sizeof(arr2[0]);
    bubble_sort(arr2, len2, sizeof(stu), struct_cmp);
    for (i = 0; i < len2; i++)
    {
        printf("%s %f ", arr2[i].name, arr2[i].score);
    }
    printf("\n");
    char *arr3[] = { "aaa", "dddd", "cccc", "bbbb" };
    int len3 = sizeof(arr3) / sizeof(arr3[0]);
    bubble_sort(arr3, len3, sizeof(char *), str_cmp);
    for (i = 0; i < len3; i++)
    {
        printf("%s ", arr3[i]);
    }
    printf("\n");
    system("pause");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xy294636185/article/details/80216216