课外拓展2.实现qsort函数及模拟实现qsort函数

简介: 课外拓展2.实现qsort函数及模拟实现qsort函数

qsort函数和qsort函数的模拟实现


一,qsort函数的实现


#define _CRT_SECURE_NO_WARNINGS 1
//qsort函数
#include<stdio.h>
#include<stdlib.h>
void print(int arr[], int sz) {
  for (int i = 0; i < sz; i++)
    printf("%d ",arr[i]);
  printf("\n");
}
int compare(const void *e1,const void *e2) {
  return *(int*)e1 - *(int*)e2;
}
int main() {
  int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
  int sz = sizeof(arr) / sizeof(arr[0]);
  //排序
  qsort(arr,sz,sizeof(arr[0]),compare);
  //输出
  print(arr, sz);
  return 0;
}
//qsort函数的基本结构(快速排序)
//void qsort(void* base, size_t num, size_t size, int (*compare)(const void*, const void*));
//void* base指的是排序数据首元素的地址。
//size_t num指的是排序数据的个数;
//size_t size指的是每个元素的大小(占几个字节);因为传进来的数据首元素的类型未知,需要认为的输入字节大小;
//int (*compare)(const void*, const void*)指的是一个函数指针;指向一个函数。这个是留给使用者写的自定义函数。
//因为qsort函数适用于所有类型的比较排序,所以指针类型都是void,但是使用者是一定知道比较的数据类型,故把这个函数留给使用者写
//
//int compare(const void* e1, const void* e2) {
//  return *(int*)e1 - *(int*)e2;
//}
//我们来分析一下这个该由我们自己书写的函数
//首先,参数是两个无类型的空指针,代表着这个函数可以用于任何类型的数据相比较
//这个函数的返回值一定是int整型,因为在qsort函数中是根据这个函数的返回值进行排序的,返回值大于0是就是升序排序,
//返回值小于0就是降序排序。


qsort函数的基本结构(快速排序)

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

void* base指的是排序数据首元素的地址。

size_t num指的是排序数据的个数;

size_t size指的是每个元素的大小(占几个字节);因为传进来的数据首元素的类型未知,需要认为的输入字节大小;

       int (*compare)(const void*, const void*)指的是一个函数指针;指向一个函数。这个是留给使用者写的自定义函数。

       因为qsort函数适用于所有类型的比较排序,所以指针类型都是void,但是使用者是一定知道比较的数据类型,故把这个函数留给使用者写

int compare(const void* e1, const void* e2) {

   return *(int*)e1 - *(int*)e2;

}

       我们来分析一下这个该由我们自己书写的函数

首先,参数是两个无类型的空指针,代表着这个函数可以用于任何类型的数据相比较

           这个函数的返回值一定是int整型,因为在qsort函数中是根据这个函数的返回值进行排序的,返回值大于0是就是升序排序,

返回值小于0就是降序排序。


二,qsort函数的模拟实现


//模拟实现qsort函数
#include<stdio.h>
//交换函数(也可以不单独写成函数,但是我觉得主要可读性更好)
void swap(char* buf1, char* buf2,size_t width) {
  int i;
  for (i = 0; i < width; i++) {
    char temp = *buf1;
    *buf1 = *buf2;
    *buf2 = temp;
    buf1++;
    buf2++;
  }
}
//写qsort必须写的函数,必须由使用者写,虽然我们这里是模拟实现qsort函数,但是仍需要写这个。
int compare(const void* e1, const void* e2) {
  //根据返回值进行排序(来绝对是升序还是降序)
  return *(char*)e1 - *(char*)e2;
}
void bubble_sort(void* base, size_t sz, size_t width, int (*compare)(const void*, const void*)) {
  int i, j;
  //外层循环控制总趟数
  for (i = 0; i < sz-1; i++) {//这里一定是sz减一,sz是数组长度,下标只能到sz-1;
    for (j = 0; j < sz - i- 1; j++) {
      //这个地方是妥妥的重点了,为什么要强制类型转换为char* 类型?
      //其实这个地方我觉得转换为其他类型也行,但是qsort函数是可以对所有数据类型进行排序的,如果只是对单一的一种数据排序,那的确是可以的
      //但是我们这里是模拟实现qsort函数的功能,故,我们这里转换为char* 类型
      //还有一个原因,char*类型的指针解引用时只走一个字节,众所周知,字节是代码的最小存储单位了,其他无论什么类型的数据都是以字节论的
      if (compare((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
        swap(((char*)base + j * width), ((char*)base + (j + 1) * width),width);
      //我们再来理解一下这个(char*)base + j * width是什么意思呢?
      //首先这个char*我是已经将过了的,接下来我们要解释的就是j*width的含义
      //因为我们对未知类型的数据进行排序,(int*)+1是走四个字节,但对它本身来说就只移动了一个元素长度
      //那如果是(int*)+i呢?我们是不是就可以理解为从头开始往后面走了i个元素,拿这个例子与上面一对比,这就十分明确了
      //j*width的意思就是待排序数据一个元素所占用的长度,也就是往后面移动了一位。
    }
  }
}
int main() {
  int arr[] = { 1,3,5,7,9,2,4,6,8,0 };
  bubble_sort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), compare);
  int i = 0;
  for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
    printf("%d",arr[i]);
  }
  printf("\n");
  char arr1[] = "hello world";//这里我准备了两个例子供大家参考
  bubble_sort(arr1, sizeof(arr1) / sizeof(arr1[0]), sizeof(arr1[0]), compare);
  for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
    printf("%c",arr1[i]);
  printf("\n");
  return 0;
}


qsort函数,俗称快排,它可以对任意数据类型的数据进行排序,这是很方便的,希望大家一定要搞熟。


希望大家能学到东西,静待大家的斧正和指教。

目录
相关文章
|
4月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
11月前
|
搜索推荐 程序员 C语言
C语言学习系列-->【关于qsort函数的详解以及它的模拟实现】
C语言学习系列-->【关于qsort函数的详解以及它的模拟实现】
52 0
C生万物 | 从浅入深理解指针【第四部分】(qsort的使用和模拟实现)
C生万物 | 从浅入深理解指针【第四部分】(qsort的使用和模拟实现)
|
10月前
|
程序员
qsort函数的模拟实现
qsort函数的模拟实现
48 1
|
11月前
【冒泡排序】模仿qsort的功能实现一个通用的冒泡排序
【冒泡排序】模仿qsort的功能实现一个通用的冒泡排序
72 0
|
算法 搜索推荐 编译器
qsort函数详解(C语言排序界的神兵)
qsort函数详解(C语言排序界的神兵)
|
C语言
qsort函数的使用和模拟实现
qsort函数的使用和模拟实现
60 0
qsort函数的使用和模拟实现
|
算法
C进阶:指针(2),qsort函数,模拟实现冒泡算法(上)
C进阶:指针(2),qsort函数,模拟实现冒泡算法
67 0
|
算法 搜索推荐
C进阶:指针(2),qsort函数,模拟实现冒泡算法(下)
C进阶:指针(2),qsort函数,模拟实现冒泡算法(下)
72 0
|
搜索推荐 C语言
【C语言】“qsort函数详解”与“使用冒泡思想模拟使用qsort”
qsort的介绍: qsort ()函数是 C 库中实现的快速排序算法,包含在 stdlib.h 头文件中 此函数需要四个参数void qsort(void* *base, size_t nitems, size_t size, int (compar)(const void * , const void)) char* base —— 指向要排序的数组首元素地址的指针 size_t nitems —— 要排序数组的元素个数 size_t size —— 数组每个元素大的小 (有非常重要的作用) int compar(const void *,const void *) —— 由使用者提供的一