你应该知道的C语言干货(6)(qsort详解及模拟实现)

简介: 我们知道包含stdlib.h头文件后,就可以使用qsort这个库函数,接下来让我们了解他。

我们知道包含stdlib.h头文件后,就可以使用qsort这个库函数,接下来让我们了解他。


#qsort 函数介绍及举例使用

94a051e9132e41c2a671f83f7b815a01.png

qsort第一个参数是要排序的数组的首地址,第二个参数是要排序的数据数量,有几个,第三个参数是要排序的那个参数占几个字节,最后一个参数是函数指针,是让用户进行使用的函数,可以让用户对任意类型数据进行排序,一会儿我们会说到。


快速排序,可以实现像冒泡排序等的排序,同时能够对结构体排序时,将其其他数据一同排序,这是他的一大优点,接下来看举例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Qsort
{
  char name[8];
  int age;
}Qsort;
int cmp(void* p1, void* p2)
{
  return ((Qsort*)p1)->age - ((Qsort*)p2)->age;
}
int main()
{
  Qsort People[3];
  memset(People, 0, sizeof(Qsort) * 3);
  for (int i = 0; i < 3; i++)
  {
    scanf("%s %d", People[i].name, &People[i].age);
    getchar();
  }
  qsort(People,3,sizeof(Qsort), cmp);
  for (int i = 0; i < 3; i++)
  {
    printf("%s %d\n", People[i].name, People[i].age);
  }
  return 0;
}


运行截图如下:

59f3169846554c4ab86882f19753fbbe.png

实现了年龄的排序,同时将名字也进行了移动,非常好用,接下来再举几个例子:


Example 1:对整数排序

#include <stdio.h>
#include <stdlib.h>
int cmp(const void* a, const void* b)
{
  return *(int*)a - *(int*)b;
}
int main()
{
  int arr[10] = { 1,2,3,7,3,1,5,9,2,5 };
  qsort(arr, 10, sizeof(int), cmp);
  for (int i = 0; i < 10; i++)
  {
    printf("%d ", arr[i]);
  }
  return 0;
}

4dd1e2c7aa5a474d8363ffe17ec0b583.png


Example 2:对浮点数排序

#include <stdio.h>
#include <stdlib.h>
int cmp(const void* a, const void* b)
{
  return *(float*)a - *(float*)b;
}
int main()
{
  float farr[5] = { 3.14,5.20,13.14,6.6,11.1 };
  qsort(farr, 5, 4, cmp);
  for (int i = 0; i < 5; i++)
  {
    printf("%.2f\n", farr[i]);
  }
  return 0;
}

5e0de2b9d9e74031943fc57d7b799547.png


Example 3:对名字排序

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct Qsort
{
  char name[8];
  int age;
}Qsort;
int cmp(void* p1, void* p2)
{
  return strcmp(((Qsort*)p1)->name , ((Qsort*)p2)->name);
}
int main()
{
  Qsort People[3];
  memset(People, 0, sizeof(Qsort) * 3);
  for (int i = 0; i < 3; i++)
  {
    scanf("%s %d", People[i].name, &People[i].age);
    getchar();
  }
  qsort(People,3,sizeof(Qsort), cmp);
  for (int i = 0; i < 3; i++)
  {
    printf("%s %d\n", People[i].name, People[i].age);
  }
  return 0;
}

e71aaee2263d444c89af620a94800a10.png


你学会如何使用qsort了吗?如果还有疑问,接下来在qsort的模拟实现中也许会解答你的疑问惑


#qsort函数模拟实现

这里的核心排序我们将使用冒泡排序替代,这里本应该使用快速排序作为核心,但这里不涉及数据结构,就不多做介绍,感兴趣可以自己使用快速排序

#include <stdio.h>
#include <string.h>
#include <assert.h>
typedef struct stu
{
  char name[20];
  int age;
}stu;
int cmp(void* p1, void* p2);
void my_qsort(void* base, size_t num, size_t sz, int (*cmp)(const void*
                                                    ,const void*));
void swap(char* a, char* b, int sz);
int main()
{
  //qsort(base,num,size,cmp)
  stu student[3] = { {"nene",23},{"haha",21},{"miao",22} };
  my_qsort(student, 3, sizeof(stu), cmp);
  for (int i = 0; i < 3; i++)
  {
    printf("%s %d\n", student[i].name, student[i].age);
  }
  return 0;
}
//因为我们不知道要比较的数据是什么类型,所以干脆传viod*类型,这样用户使用时
//想比较什么类型的数据自己强制转换就好,就是用cmp函数,将void*类型的参数强
//制转换成int*等类型,解引用后返回差值,或者是大小,返回的值将作为是否进行
//数据交换的依据。
void my_qsort(void* base, size_t num, size_t sz, int (*cmp)(const void*,
                                                         const void*))
{
  assert(base);  //断言,判断传上来的指针是否为NULL
  for (int i = 0; i < num - 1; i++)
  {
    for (int j = 0; j < num - i - 1; j++)
    {
      if (cmp((char*)base + sz * j, 
                            (char*)base + sz * (j + 1)) > 0)
        swap((char*)base + sz * j,  
                            (char*)base + sz * (j + 1), sz); 
                //在这里,根据cmp的返回值决定是否交换
    }
  }
}
int cmp(void* p1, void* p2)
{
  return strcmp(((stu*)p1)->name, ((stu*)p2)->name);
}
//这个函数我们的参数设置为char*,因为我们依然不知道用户想要排序什么
//类型的数据,但是我们交换时不能用void*,void*可以接受任何类型的数据
//但是他没有大小,不能解引用,所以传上来sz这个大小,然后每个字节进行交换
void swap(char* a, char* b, int sz)
{
  assert(a && b);
  while (sz--)
  {
    char temp = *a;
    *a = *b;
    *b = temp;
    a += 1;
    b += 1;
  }
}

dffd2352ae2d4f7db93e8bdfc8dc8c80.png


#下期预告

指针进阶知识:

1.字符指针

2.指针数组

3.数组指针

4.一维数组传参,一级指针传参,区别

  二维数组传参,二级指针传参,区别

目录
相关文章
|
6月前
|
C语言
C语言-----qsort函数的功能以及模拟实现
C语言-----qsort函数的功能以及模拟实现
58 1
|
6月前
|
搜索推荐 C语言
c语言从入门到实战——回调函数与qsort的讲解和模拟实现
回调函数是一个函数,它作为参数传递给另一个函数,并且能够在该函数内部被调用。在C语言中,回调函数通常被用于实现事件处理和排序算法中。 `qsort`是C标准库中的一个排序函数,它可以对任意类型的数组进行排序。`qsort`需要三个参数:要排序的数组、数组元素的个数和一个指向回调函数的指针。回调函数必须满足两个条件:能够比较数组中的元素,返回一个整数表示它们之间的大小关系;并且它应该能够被`qsort`函数调用。 回调函数是一种在编程中广泛使用的技术,它允许一个函数作为参数传递给另一个函数,并在需要时被调用。这种机制使得代码更加灵活和可重用。
63 0
|
6月前
|
C语言
c语言进阶部分详解(经典回调函数qsort()详解及模拟实现)
c语言进阶部分详解(经典回调函数qsort()详解及模拟实现)
72 0
|
算法 编译器 C语言
【C语言】指针的进阶(三)—— 模拟实现qsort函数以及指针和数组的笔试题解析
【C语言】指针的进阶(三)—— 模拟实现qsort函数以及指针和数组的笔试题解析
45 0
|
1月前
|
算法 搜索推荐 C语言
【C语言篇】深入理解指针4(模拟实现qsort函数)
【C语言篇】深入理解指针4(模拟实现qsort函数)
23 2
|
25天前
|
C语言
【c语言】qsort函数及泛型冒泡排序的模拟实现
本文介绍了C语言中的`qsort`函数及其背后的回调函数概念。`qsort`函数用于对任意类型的数据进行排序,其核心在于通过函数指针调用用户自定义的比较函数。文章还详细讲解了如何实现一个泛型冒泡排序,包括比较函数、交换函数和排序函数的编写,并展示了完整的代码示例。最后,通过实际运行验证了排序的正确性,展示了泛型编程的优势。
20 0
|
1月前
|
搜索推荐 C语言
深入浅出理解 C 语言中的 qsort 函数
深入浅出理解 C 语言中的 qsort 函数
|
6月前
|
编译器 C语言
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(下)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
42 0
|
5月前
|
搜索推荐 C语言
c语言qsort函数的模拟实现
c语言qsort函数的模拟实现
28 1
|
5月前
|
算法 搜索推荐 C语言
深入了解C语言的qsort函数:原理及相关知识
深入了解C语言的qsort函数:原理及相关知识
76 1