广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >【C语言】用冒泡排序实现my_qsort
  • 507
分享到

【C语言】用冒泡排序实现my_qsort

c语言排序算法开发语言 2023-10-07 18:10:40 507人浏览 独家记忆
摘要

大家好,我是苏貝,本篇博客带大家了解如何用冒泡排序实现my_qsort,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 一. 前言二. 冒泡排序三.

大家好,我是苏貝,本篇博客带大家了解如何用冒泡排序实现my_qsort,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

一. 前言

用冒泡排序实现my_qsort?你或许觉得没有必要这样做,有现成的qsort函数,为什么还要自己写一个呢?于我而言,它可以让我对冒泡排序和qsort函数的印象加深。至于这到底有没有用,仁者见仁,智者见智吧。好了,就说这么多,现在让我们来回忆一下什么是冒泡排序和qsort函数。了解qsort函数


二. 冒泡排序

冒泡排序的原理:从左往右,依次比较相邻元素的大小,若符合条件,则两元素位置交换,每一趟可以找出最大值或最小值,并显示在序列的最右边。注意:冒泡排序只能排序整形序列,而qsort函数可以排序任意类型的序列

以想要升序排序为例,数组{5,2,4,3},条件:如果相邻元素的左边>右边,则两元素位置交换。第一趟:5>2,交换位置。5>4,交换位置。5>3,交换位置。所以第一趟结束后数组为{2,4,3,5}。第二趟:2<4,不符合条件,位置不变。4>3,交换位置。所以第二趟结束后数组为{2,3,4,5}。第三趟,2<3,位置不变

代码:

void bubble_sort(int arr[], int sz){int i = 0;//排几趟for (i = 0; i < sz - 1; i++){int j = 0;//一趟排几次for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}}int main(){int arr[] = { 9,8,7,6,5,4,3,2,1 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");}

结果为:
在这里插入图片描述


三. 4个参数

3.1 第一个参数void* base

回顾上面的bubble_sort函数,它的第一个参数是int arr[ ],也可以写成int* arr,意思是接受一个整形数组的首元素地址。可是我们想要的是能接受任意类型的指针,所以用int* 就不合适,采用void* (void* 能接受任意类型的指针) ,所以第一个参数写为void* base

3.2 第二个参数szie_t num

上面的bubble_sort函数的第二个参数是int sz,代表数组有多少个元素,其实用int sz也可以,只是如果我们想更贴近qsort函数的话,将int改成size_t(无符号整型)也没有问题,写成szie_t num

3.3 第三个参数szie_t size

上面的bubble_sort函数并没有第三个参数,但是qsort函数有,意思是数组中的一个元素占多少个字节。因为我们不知道要排序的数组是什么类型的,所以如果没有第三个参数,我们无法表示出除首元素以外的地址,也就无法交换相邻元素

3.4 第四个参数int ( * cmp)(const void* e1,const void* e2)

第四个参数是用来判断相邻元素的关系,不能直接使用>,<,=的原因是如果我们想排序多个字符串,那么我们是不能使用>,<,=的,我们需要使用strcmp函数。不同类型的数组排序的函数可能不一样,像qsort函数一样,程序员又不知道用户想要排序的是什么类型的数组,所以程序员只能用函数指针cmp来接收用户自己写的cmp函数,而用户当然知道自己想要排序的数组的类型,所以用户能写出判断相邻元素的关系的函数

cmp函数的细节:
1.e1和e2是相邻元素的地址,被const修饰,保护e1和e2不能被修改
2.因为不知道排序的数组是什么类型的,所以e1和e2都是void * 类型的
3.如果相邻元素的左边>右边,返回>0的数;左边==右边,返回0;左边<右边,返回<0的数。所以返回值的类型为int

void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1,const void* e2)){}

四. bubble_sort函数

虽然函数的参数变化了很多,但函数原理并没有改变,依旧是比较相邻元素的大小,若符合条件,则两元素位置交换,每一趟可以找出最大值或最小值,并显示在序列的最右边。所以下面的框架不变(只将之前的sz变成了num),变得只是第二个for循环里面的内容,而里面的内容就是判断相邻元素的左边是否大于右边(以想要升序排序为例),如果是则交换位置,否则位置不变

void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1,const void* e2)){int i = 0;//排几趟for (i = 0; i < num - 1; i++){int j = 0;//一趟排几次for (j = 0; j < num - 1 - i; j++){}}}

好的,那我们现在就想办法如何填写里面的代码,先是判断相邻元素的大小,用cmp函数,函数的两个参数分别为相邻元素的地址。那它们的地址该如何表示呢?首元素地址就是base,不用多说,那第二个元素呢?base+1?不行,我们不知道base的具体类型,所以base+1不知道会跳过几个字节。
那不妨将base强制类型转化为char* ,这样第二个元素(下标为1)的地址为(char*)base+1* size,第三个元素(下标为2)的地址为(char*)base+2* size,所以下标为j的地址为(char*)base+ j * size,代码为:

if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){}

好的,那我们继续完善if语句后面的代码,代码的目的是将两元素交换位置,编写swap函数实现交换功能,swap函数的第一、二个参数自然是相邻元素的地址,即(char*)base + j * size, (char*)base + (j + 1) * size,它们都是char * 类型的,所以用两个char * 类型的指针来接收。
但问题又来了,我们平时实现a与b交换,是通过一个变量c来进行的,如下:

int a = 10;int b = 20;int c = a;a = b;b = c;

上面能交换的原因是我们知道了a和b的类型都是int,所以再创造一个int类型的变量作它们的中转站,即可实现交换。但我们事先并不知道数组的类型,所以不能创建一个和数组同类型的变量实现交换。那不如将两元素的每一个字节都交换(如下图),刚好它们是用char * 指针buf1、buf2来接收的,buf1++,buf2++即可访问两元素的每一个字节,因此我们也需要数组元素的字节数size作为swap函数的第三个参数
在这里插入图片描述
所以if语句后面的代码为:

swap((char*)base + j * size, (char*)base + (j + 1) * size, size);

swap函数:

void swap(char* buf1, char* buf2, size_t size){int i = 0;for (i = 0; i < size; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}}

所以bubble_sort函数的全部代码为:

void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1,const void* e2)){int i = 0;//排几趟for (i = 0; i < num - 1; i++){int j = 0;//一趟排几次for (j = 0; j < num - 1 - i; j++){if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}}

五. 排序

对任意类型的数组排序都需要下面的代码,故把这些代码单独放在最前面,其余的main函数和cmp函数都因数组类型的变化而有所改变,所以将main函数和cmp函数单独写出来

void swap(char* buf1, char* buf2, size_t size){int i = 0;for (i = 0; i < size; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}}void bubble_sort(void* base, size_t num, size_t size, int (*cmp)(const void* e1,const void* e2)){int i = 0;//排几趟for (i = 0; i < num - 1; i++){int j = 0;//一趟排几次for (j = 0; j < num - 1 - i; j++){if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0){swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}}

5.1 对整型数组排序(char/short/int/long)

字符在内存中存储的是字符的ASCII码值,ASCII码是整型,所以char的写法同int

void cmp_int(const void* e1, const void* e2){return *(int*)e1 - *(int*)e2;//升序//return *(int*)e2 - *(int*)e1;//降序}int main(){int arr[] = { 9,8,7,6,5,4,3,2,1 };int sz = sizeof(arr) / sizeof(arr[0]);//升序bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);//打印数组int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}printf("\n");return 0;}

在这里插入图片描述

5.2 对浮点型数组排序(float/double)

void cmp_double(const void* e1, const void* e2){return *(double*)e1 > *(double*)e2 ? 1 : -1;//升序//return *(double*)e1 < *(double*)e2 ? 1 : -1;}int main(){double arr[] = { 3.2 ,4.5, 2.4, 1.3 };int sz = sizeof(arr) / sizeof(arr[0]);//升序bubble_sort(arr, sz, sizeof(arr[0]), cmp_double);//打印数组int i = 0;for (i = 0; i < sz; i++){printf("%lf ", arr[i]);}printf("\n");return 0;}

在这里插入图片描述

5.3 对字符串长度排序

void cmp_string(const void* e1, const void* e2){return strlen((char*)e1) - strlen((char*)e2);//升序//return strlen((char*)e2) - strlen((char*)e1);//降序}int main(){char arr[][20] = { "helloworld","yes,sir","dian ge zan ba" };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr[0], sz, sizeof(arr[0]), cmp_string);int i = 0;for (i = 0; i < sz; i++)printf("%s\n", arr[i]);return 0;}

在这里插入图片描述

5.4 对字符串大小排序

void cmp_string(const void* e1, const void* e2){return strcmp((char*)e1, (char*)e2);//升序//return strcmp((char*)e2, (char*)e1);//降序}int main(){char arr[][20] = { "helloworld","yes,sir","dian ge zan ba" };int sz = sizeof(arr) / sizeof(arr[0]);//升序bubble_sort(arr, sz, sizeof(arr[0]), cmp_string);//打印数组int i = 0;for (i = 0; i < sz; i++){printf("%s\n", arr[i]);}printf("\n");return 0;}

在这里插入图片描述

5.5 对结构体排序

struct Stu{char name[20];int age;};void cmp_stu_by_age(const void* e1, const void* e2){return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;//升序//return ((struct Stu*)e2)->age - ((struct Stu*)e1)->age;//降序}int main(){struct Stu arr[] = { {"zhang",20},{"lisi",10},{"wangwu",30} };int sz = sizeof(arr) / sizeof(arr[0]);//升序bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);//打印int i = 0;for (i = 0; i < sz; i++){printf("%s\t", arr[i].name);printf("%d\n", arr[i].age);}printf("\n");return 0;}

在这里插入图片描述


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

来源地址:https://blog.csdn.net/qq_75000174/article/details/132915133

--结束END--

本文标题: 【C语言】用冒泡排序实现my_qsort

本文链接: https://www.lsjlt.com/news/424765.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 【C语言】用冒泡排序实现my_qsort
    大家好,我是苏貝,本篇博客带大家了解如何用冒泡排序实现my_qsort,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️ 目录 一. 前言二. 冒泡排序三. ...
    99+
    2023-10-07
    c语言 排序算法 开发语言
  • C语言详解冒泡排序实现
    目录前言一、冒泡排序是什么二、具体步骤1.代码解释2.读入数据总结前言 在排序中,有各种各样的排序方式,今天我们将要来介绍《冒泡排序》。今天会从冒泡排序的具体意义和他的操作来展开。 ...
    99+
    2022-11-13
  • c语言冒泡排序怎么实现
    C语言冒泡排序的实现步骤如下:1. 定义一个数组来存储待排序的元素。2. 使用两层循环来比较相邻两个元素的大小,并进行交换。3. 外...
    99+
    2023-08-25
    c语言
  • c语言入门3(冒泡排序)
    #include <stdio.h> struct student //结构体 {char name[21];char score;};int ma...
    99+
    2023-06-03
  • C语言冒泡排序超全面实现流程
    目录普通版冒泡排序qosrt函数终极版冒泡排序终极版冒泡排序整体测试代码普通版冒泡排序 冒泡排序想必大家都很了解了吧,冒泡排序的算法思想就是两两比大小,一轮一轮比,每比完一轮排出一个...
    99+
    2023-01-13
    C语言冒泡排序原理 C语言冒泡排序算法
  • C语言中的冒泡排序问题
    目录冒泡排序的原理冒泡排序的步骤冒泡排序代码冒泡排序两种不同循环方法原理总结冒泡排序的原理 冒泡排序的步骤 假设我们现在有一个无序数组 arr[] = { 2,9,1,3,7,6 ...
    99+
    2022-12-27
    C语言冒泡排序 C冒泡排序 冒泡排序
  • C语言中冒泡排序算法详解
    目录一、算法描述二、算法分析三、完整代码总结一、算法描述 比较相邻两个元素,如果第一个比第二个大则交换两个值。遍历所有的元素,每一次都会将未排序序列中最大的元素放在后面。假设数组有 ...
    99+
    2022-11-12
  • C语言每日练习之冒泡排序
    目录分析代码实现运行结果总结分析 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 冒泡排序(这里只讨论从小到大排序)可以通过二种方式实现,分别是将最小...
    99+
    2022-11-12
  • C语言冒泡排序的方式介绍
    这篇文章主要介绍“C语言冒泡排序的方式介绍”,在日常操作中,相信很多人在C语言冒泡排序的方式介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言冒泡排序的方式介绍”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-20
  • C语言中qsort函数用法及用冒泡排序实现
    目录一、qsort函数简介二、qsort函数的使用1.整型数组排序2.字符串排序3.字符串长度排序4.浮点型数组排序5.结构体类型排序三、冒泡排序实现qsort函数的功能1.冒泡排序...
    99+
    2022-11-13
    C语言 qsort函数使用 C语言 qsort 冒泡排序 C语言 qsort
  • C语言qsort函数用冒泡排序实现过程详解
    目录前言1.冒泡排序的实现1.1冒泡排序的概念1.2具体代码的实现2.qsort函数3.qsort函数的实现前言 这篇文章就是指针进阶的收尾环节了,相信看过C语言进阶—&...
    99+
    2023-02-14
    C语言qsort函数 C语言冒泡排序实现qsort函数
  • C语言实现冒泡排序算法的示例详解
    目录1. 问题描述2. 问题分析3. 算法设计动图演示4. 程序设计设计一设计二结论5. 流程框架6. 代码实现7. 问题拓展1. 问题描述 对N个整数(数据由键盘输入)进行升序排列...
    99+
    2022-11-13
  • C语言实现冒泡排序算法代码怎么写
    这篇文章主要介绍“C语言实现冒泡排序算法代码怎么写”,在日常操作中,相信很多人在C语言实现冒泡排序算法代码怎么写问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言实现冒泡排序算法代码怎么写”的疑惑有所帮助!...
    99+
    2023-06-29
  • C语言实现冒泡排序的思路以及过程
    目录C语言实现<冒泡排序>整体思路代码实现C语言实现<冒泡排序> 你们好!我是飞人!此篇文章是我进入IT行业第一篇博客,若有不妥之处,欢迎指点。 此篇讲解冒泡...
    99+
    2022-11-12
  • c语言冒泡排序和选择排序的使用代码
    目录1.冒泡排序2.选择排序区别总结1.冒泡排序 冒泡排序将一个列表中的两个元素进行比较,并将最小的元素交换到顶部。两个元素中较小的会冒到顶部,而较大的会沉到底部,该过程将被重复执行...
    99+
    2022-11-13
  • C语言冒泡排序算法代码详解
    今天我们来用C语言实现一下冒泡排序 首先我们来了解一下什么叫做冒泡排序,冒泡顾名思义把质量轻的气体(如二氧化碳一样)浮到水面上(如可乐中的二氧化碳),因此冒泡排序的原理就是N个元素在...
    99+
    2022-11-13
  • 深入了解C语言冒泡排序优解
    目录1:直接冒泡2:函数冒泡3:冒泡优化总结:1:直接冒泡 #include<stdio.h> int main() { int i,j; int ...
    99+
    2022-11-12
  • C语言中冒泡排序的示例分析
    这篇文章给大家分享的是有关C语言中冒泡排序的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。(壹)冒泡排序1.1冒泡排序的设计冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排...
    99+
    2023-06-29
  • 基于Go语言实现冒泡排序算法
    目录冒泡排序图片演示普通的冒泡排序算法优化算法小结冒泡排序 冒泡排序是交换排序中最简单的一种算法。 算法思路: 遍历数组,相邻的两个元素进行比较,以升序为例,如果前面的元素大于后面的...
    99+
    2022-12-08
    Go语言实现冒泡排序算法 Go语言冒泡排序 Go 冒泡排序
  • C++中如何实现冒泡排序
    这篇文章给大家介绍C++中如何实现冒泡排序,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C++冒泡排序代码示例:#include < iostream.h> #include&...
    99+
    2023-06-17
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作