qsort函数的讲解

简介: qsort函数的讲解

qsort函数的介绍

qsort(即quick sort)是C语言中的一个标准库函数,用于对数组进行快速排序。它是一种高效的排序算法,具有较好的平均和最坏情况下的时间复杂度。

qsort函数的声明如下:

void qsort(void* base, size_t nmemb, size_t size, int (compar)(const void, const void*));

参数解释如下:

base:指向要排序的数组的第一个元素的指针。

nmemb:数组中元素的数量。

size:每个元素的大小(以字节为单位)。

compar:指向比较函数的指针,用于定义元素之间的排序顺序。

比较函数compar用于定义元素之间的排序顺序,它接收两个指向元素的指针,通常为 void* 类型。比较函数需要返回一个整数值,代表两个元素的大小关系:

如果返回值小于0,表示第一个元素应该排在第二个元素之前。

如果返回值等于0,表示两个元素相等。

如果返回值大于0,表示第一个元素应该排在第二个元素之后。

使用qsort函数,可以对各种类型的数组进行排序,包括整型、浮点型、字符型以及自定义结构体等。

整形排序

我们刚刚了解到了,对于排序不同类型的数据,需要自定义不同的compar函数,接下来看一下整形的例子

#include <stdio.h>
#include <stdlib.h>
// 比较函数,用于升序排序
int compare(const void* a, const void* b) {
    return (*(int*)a - *(int*)b);
}
int main() {
    int arr[] = {5, 2, 8, 1, 9, 3};
    int size = sizeof(arr) / sizeof(arr[0]);
    qsort(arr, size, sizeof(int), compare);
    printf("升序排序结果:");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

运行程序如下:

接下来就直接只展示不同类型的数据compare函数

浮点型排序

int cmp_float(const void* e1, const void* e2)
{
  return (int)(*(float*)e1 - *(float*)e2);
}

字符串排序

int cmp_str_size(const void* e1, const void* e2)
{
  return strcmp((char*)e1, (char*)e2);
}

结构体排序

int cmp_by_name(const void* e1, const void* e2)
{
  return (int)(((stu*)e1)->age - ((str*)e2)->age);
}

结构体中文名字排序示例

上述结构体排序是年龄,接下来我们来比较结构体中按中文名字排序

#include <stdio.h>
#include <stdlib.h>//使用qsort函数需要包含头文件
#include <string.h>
struct stu
{
  char name[20];
  int age;
};
int cmp_name(const void* e1, const void* e2)
{
  return strcmp(((struct stu*)e1)->name , ((struct stu*)e2)->name);
}
int main()
{
  struct stu arr[3] = { {"张三", 20}, {"李四", 18}, {"王五", 36} };
  int sz = sizeof(arr) / sizeof(arr[0]);
  qsort(arr, sz, sizeof(arr[0]), cmp_name);
  for (int i = 0; i < sz; i++)
  {
    printf("%s %d ", arr[i].name, arr[i].age);
    printf("\n");
  }
  return 0;
}

qsort函数的模拟

了解了qsort函数的使用,我们来尝试模拟一下qsort函数的实现

#include<stdio.h>
void swap(char* p1, char* p2, int width) 
{
  for (int i = 0; i < width; i++) //不知道是什么类型,所以要一个字节一个字节来进行交换
  {
    char temp = *p1;
    *p1 = *p2;
    *p2 = temp;
    p1++;
    p2++;
  }
}
int compare(const void* p1, const void* p2) 
{
  return *((int*)p1) - *((int*)p2);
}
//void* base - 要求排序不同类型的数组,void*恰好能接收任意类型的数据
//int num - 元素个数
//int width - 一个元素的大小
//int (*compare)(const void* p1, const void* p2)  函数传参函数指针接收
int my_qsort(void* base, int num, int width,int (*compare)(const void* p1, const void* p2))) 
{
  for (int i = 0; i < num - 1; i++) 
  {
    for (int j = 0; j < num - 1 - i; j++) 
    {
      //强制类型转化为char*型的数据,是因为一开始不知道数组的类型
            //如果要访问数据的话,只能一个字节一个字节的访问
      //这样有利于排序各种类型的数     
      if (compare((char*)base + j * width,(char*)base + (j + 1) * width) > 0) 
      {
        //写一个Swap函数来交换
        swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
      }
    }
  }
}
int print(int arr[], int num)
{
  for (int i = 0; i < num; i++)
  {
    printf("%d ", arr[i]);
  }
}
int main() 
{
  int arr[10] = { ![11,23,54,65,87,34,59,55,66,44]
  int num = sizeof(arr) / sizeof(arr[0]);//计算数组中的元素个数
    //打印排序前的数组
    printf("排序前为:");
    print(arr, num);
  printf("\n");
  my_qsort(arr, num, sizeof(arr[0]), compare);
  //打印排序后的数组
    printf("排序后为:");
  print(arr, num);
  return 0;
}

运行结果如下:

内容就分享到这里,各位看客老爷万福金安。

目录
相关文章
|
6月前
qsort函数专题
qsort函数专题
37 2
|
5月前
|
C语言
qsort函数的应用
qsort函数的应用
31 0
|
5月前
|
C语言
【C语言】: 快速排序——qsort函数的介绍
【C语言】: 快速排序——qsort函数的介绍
43 0
qsort函数和模拟实现qsort函数
qsort函数和模拟实现qsort函数
|
6月前
|
搜索推荐
【qsort函数实现】
【qsort函数实现】
|
6月前
|
JavaScript 前端开发
sort函数排序
sort函数排序
55 0
sort函数排序
|
6月前
|
算法 搜索推荐 C语言
快速排序和qsort函数详解详解qsort函数
快速排序和qsort函数详解详解qsort函数
85 0
|
11月前
|
容器
sort函数
sort函数
qsort函数详细讲解以及利用冒泡排序模拟实现qsort函数
qsort函数详细讲解以及利用冒泡排序模拟实现qsort函数
69 0
|
搜索推荐 C语言
冒泡排序与qsort函数详解
提及到排序,冒泡排序算是一个很基础的排序了。那么冒泡排序到底是什么呢?冒泡排序在什么情况下使用呢?qsort函数又是什么呢?接下来我给大家通过举例来详细解释一下。
57 0