C语言----冒泡排序进阶

      冒泡排序大家应该到写过吧。但大家可能知道到的冒泡排序有两种方法。而我呢,最近学习到了另外一种方法,现在知道三种方法了。所以想与大家分享一下。但是缺点是第三种是第二种的自实现版。第一种就是我们平常写的普通冒泡排序。第二种就是qsort。第三种就是my_qsort。好那么我们就这三种冒泡排序来讲述。

普通冒泡

       大家学习肯定都是先易后难。我们也就先从大家最先学习的冒泡排序开始。当然我不知道,大家对于最常见的冒泡排序是如何理解的,我就先讲解我自己对于冒泡排序的见解。我是这样认为的。因为需要冒泡排序的话,那么就是需要排序后的数组依照升序或者降序来排序,那么我就有双循环语句来写。例如一个数组有10个元素,且下标为0的元素是最大的元素的话。那么我用下标0的元素依次与下一个元素比较,大于的话,用一个零时变量来使这两个值交换。一直到下标为9的时候停止。然后进行下一个循环。当然,因为我已经遍历了一遍确定现在的下标为9的元素是数组中最大的元素所以我们在下一次遍历的时候就可以减少对最后的元素比较。好,那么接下来我们就用代码来更加详细的讲解。

       不知道我的代码与大家想的是否有太多的不同之处。或者大家认为这样的代码还有地方可以简洁,大家可以在下方评论区不腻赐教。但其实大家看了上面的代码是否觉得有点啰嗦且繁琐啊。如果我们运气不好的话。这个代码我们要遍历36遍。空间复杂度是否有时候不好满足呀。并且我们如果后面改了,不用整型数组,我们有char类型数组的话。这个代码是不是就不能直接使用了。当然我们可以依照这个模板写一个char类型的冒牌排序,但是大家是否觉得再写一个的话,是否就有点太麻烦了。那是否有这个简单且适应其他类型排序的排序方法嘞。嘿,还真有。在c语言编辑的时候,编辑者就想到了,后面的使用可能会需要对数组进行排序,那么我就写一个库函数吧,后面额人直接使用库函数再添加一些关键数据就可以排序了。这就是我接下里想与大家分享的知识。库函数qsort。

库函数qsort

       大家也知道了我们接下来要讲的是库函数qsort。那我们先来了解qsort是什么,由什么构成的

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

       头文件:<stdlib.h> qsort()函数的功能是对数组进行排序,数组有nmemb个元素,每个元素大小为size。打大家看上面这个肯定对qsort还是不了解。那么我们直接用代码来实践解决。

      当然因为是库函数所以头文件肯定是不能少的,我只是在前面的时候写过了没有照下来,大家在使用的时候记得写出来就可以了。大家看了后,可能会想,不是说可以适用于所有类型吗。你这不是char类型吗?但是大家可以看一下,我在判断大小的时候用的是void*来接收的。为什么用void*来接收嘞。这就不得不说void*的作用了。void大家都知道,无类型,那么无类型的话是不是所有类型的可以接收,相当于一个五边形战士,你来什么对手我都可以打败。但是大家需要注意到,最大的对手自己,所有void*不可以进行就算改变。它只能接收,不能进行改变。这样大家知道我们我在判断大小的时候,返回值的时候要将p1和p2强转为char类型了吧。所有qsort可以排序任意类性数组真相大白了。我们需要在给qsort传递判断大小的时候需要用void*来接收(因为void*可以接收任意类型)。然后返回的时候再强转为数组的类型(使用者肯定知道自己需要排序的数组是什么类型),这样qsort就完美的写出了。当然我可以在写一个int类型的排序,只需要在这个代码上面修改一些部分。

       大家可以对照上面的图片,我们写另外一个类型的排序数组,不需要完全重写一个代码,我们只需要将一些关键的类型改变就可以了 。

注:qsort比较大小是使用的ascll码来比较的!!!

自实现qsort

    当我们知道qsort如何使用了后,肯定不能止步于此呀,我们要完全将这个函数吃透的话,最好直接写一个代码来实现这个功能。那么接下来我们写的就是my_qsort。大家学习了上面的代码后,就是如果自己写一个的话,需要干什么。我们就以上面的代码来。我们先写,然后总结:

int daxiao(const void *p1,const void *p2)//判断大小
{return *(int*)p1 - *(int*)p2;
}
void jiaohuan(char*p1, char*p2, size_t haa)//交换值,char类型是为了方便交换,多循环几次就交换全部了
{for (int a = 0; a < haa; a++){char count = *p1;*p1 = *p2;*p2 = count;p1++;p2++;}
}
void my_qsort(void*arr,size_t sz,size_t ha,int (*pf)( void *p1,void *p2))
{for (int a = 0; a < sz - 1; a++){for (int y = 0; y < sz - 1 - a; y++){if (pf((char*)arr + y *ha, (char*)arr + (y + 1)*ha)>0)//判断,如果大于就交换小于不管jiaohuan((char*)arr + y*ha, (char*)arr + (y + 1)*ha,ha);}}
}
void dayin(int *arr, int sz)//打印结果
{for (int yy = 0; yy < sz; yy++){printf("%d ", arr[yy]);}
}
void xixi()
{int arr[] = { 9, 8, 6, 7, 2, 3, 6, 1, 0, 12 };int sz = sizeof(arr) / sizeof(arr[0]);my_qsort(arr, sz, sizeof(arr[0]), daxiao);dayin(arr, sz);
}
int main()
{xixi();return 0;
}

        上面是my_qsort的全部代码,那么我们接下来分段来解释每段代码的作用。首先主函数和创建数组传递参数这个大家知道吧。我们先解读一下my_qsort中的数据含义。arr肯定是数组名,sz是数组元素个数,sizeof(arr[0])是数组元素大小,daxiao判断升降序。

        我们也都知道qsort一些关键数据需要用void*来接收(因为void*的特性)。但大家应该也注意到了在my_qsort最后接收数据的时候,我们使用的是int (*pf)( void *p1,void *p2)。那这个是什么嘞。首先大家要知道这个叫函数指针,因为我们在这个代码中包含了另外一个需要使用的代码,使用需要将确定其使用的指针名,数据,返回值(当然我们后面会详细的讲解一下这个是什么东西,大家现在可以先记住这个是什么东西,长什么样子)。然后进入代码里面还是经典的双循环。然后判断,那么就是我刚刚说的函数指针判断大小了

        那么我们也只是说了,这个代码只是包含的另外一个,那么这个代码是不完全的,所以我们接着就要去晚上这个判断大小的代码。因为函数指针int (*pf)( void *p1,void *p2)中*pf就是这个指针的名字。那么我们接下来( void *p1,void *p2)就是传递的参数,所以大家可以将pf((char*)arr + y *ha, (char*)arr + (y + 1)*ha)理解为子程序名(参数,参数)。那么这里了解了,我们就来完整这个代码:

      首先为什么是daxiao这个数组名,是因为在创建数组my_qsort中我们就将判断大小的囊位置确定了名字就叫daxiao所以以防程序错误,我们名字需要一样。然后也是老样子,相减返回,来确定大小。然后回到my_qsort中判断是想要升序还是降序所以交换。

     这里大家需要注意的是,为什么我们在接收数据的时候强转char类型。因为char类型只有1个字节。大家应该注意到了吧,我们传递过来的数据中除了交换的两个元素外还有一个字节大小。我们把这两个结合,大家是否想到了。1个字节在c语言数据类型中是最小的,并且使用的类型大小都是2的倍数,那么我们只需要多循环几次,岂不是就可以用1个字节依次交换就交换结束了。然后就是最后的步骤打印了。当然我们在开头就写了打印的代码了。这里就不多赘述了,我们直接看结果。

        所以自实现my_qsort只需要以下加点:

1:主函数,创建数组

2:my_qsort接收数据,双循环,判断大小(是否升降序)

3:函数指针实现判断大小

4:交换数据

5:写交换结果

         这些就是my_qsort的大概步骤了。当然还有步骤需要大家了解,大家可以多看一下来增加对这个代码的熟悉度。好了如果还有很多不对的地方,希望大家可以在下方评论区写出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/725277.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab梁单元有限元编程 | 铁木辛柯梁 | 欧拉梁 | Matlab源码 | 理论文本

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

如何恢复edge的自动翻译功能

介绍&#xff1a;对于英文不好的小伙伴&#xff0c;把英语翻译成中文是有帮助的&#xff0c;而edge可以直接对英文页面翻译这一功能更是受人喜爱&#xff0c;但是&#xff0c;最近发现这一项功能消失了。 原始界面&#xff1a; 下面展示如何恢复该功能。 1.打开edge&#xff…

day06-网路编程

#include <myhead.h>int do_add(sqlite3 *ppDb) {int numb;char name[20];int age;int salary;printf("请输入要插入的信息:");scanf("%d %s %d %d", &numb, name, &age, &salary);char sql[128] "";sprintf(sql, "INSE…

Flutter(四):SingleChildScrollView、GridView

SingleChildScrollView、GridView 遇到的问题 以下代码会报错: class GridViewPage extends StatefulWidget {const GridViewPage({super.key});overrideState<GridViewPage> createState() > _GridViewPage(); }class _GridViewPage extends State<GridViewPage&g…

vscode 通义灵码 插件自动写代码

安装插件 通义灵码安装教程-阿里云 点击立即安装 我是已经安装成功了&#xff0c;所以如下图&#xff0c;没安装的会显示安装&#xff0c;点击安装即可 安装成功之后 侧边栏会出现图标 登录 使用 在编辑框中输入 问题 &#xff0c;会自动生成代码和对应的说明

Cloud+Consul

Cloud整合Zookeeper代替Eureka-CSDN博客 Consul简介 Consul是一套开源的分布式服务发现和配置管理系统 What is Consul? | Consul | HashiCorp DeveloperConsul is a service networking solution that delivers service discovery, service mesh, and network security ca…

Redis中的RDB和AOF持久化机制(一)

Redis持久化 RDB快照(snapshot). 在默认情况下&#xff0c;Redis将内存数据库快照保存在名字为dump.rdb的二进制文件中.Redis可以进行设置,让它在"N秒内数据集至少有M个改动"这一条件被满足时&#xff0c;自动保存一次数据集。比如说&#xff0c;以下设置会让Redis…

TypeScript常见面试题第一节

题目一&#xff1a;是否了解TypeScript&#xff1f;TypeScript比JavaScript 有哪些优势&#xff1f; 一、讲解视频 CSDN视频&#xff1a; TS面试题一&#xff1a;介绍TS及TS的优势&#xff1f; B站视频&#xff1a; TS面试题一&#xff1a;介绍TS及TS的优势&#xff1f; 二、…

关于Spark中OptimizeShuffleWithLocalRead 中自己的一些理解

背景 本文基于 Spark 3.5 关于ShuffleLocalRead的作用简单的来说&#xff0c;就是会按照一定的规则&#xff0c;从一个 map Task 中连续读取多个 reduce数据 的任务&#xff0c;&#xff08;正常的情况下是读取所有map Task中特定的一个reduce数据任务&#xff09;&#xff0c…

Effective C++ 学习笔记 条款13 以对象管理资源

假设我们使用一个用来塑模投资行为&#xff08;如股票、债券等等&#xff09;的程序库&#xff0c;其中各式各样的投资类型继承自一个root class Investment&#xff1a; class Investment { /* ... */ }; // “投资类型”继承体系中的root class进一步假设&#xff0c;这个…

机器视觉 /从bottle.hdev示例程序开启HalconHDevelop征程

文章目录 概述示例程序bottle.hdev源码Step 0: PreparationsStep 1: Segmentation - 读取并显示图片Step 1: Segmentation - 创建并设置OCR模型Step 1: Segmentation - 文本分割与识别计算结果显示内存释放 导出为C代码导出为C代码配置 VS Halcon 环境VS程序执行结果HTuple hv…

LeetCode刷题---填充每个节点的下一个右侧节点指针

官方题解:LeetCode官方题解 解题思想: 因为是一棵满二叉树&#xff0c;所以除了叶子节点外的其他节点都有两个子节点。 可以根据每一层来依次遍历 从根节点开始&#xff0c;根节点的左子节点的next节点就指向根节点的右子节点 因为根节点的next节点为NULL&#xff0c;开始从根…

centOS7操作系统安装说明

一、安装前准备 在安装CentOS 7之前&#xff0c;确保你已经下载了CentOS 7的ISO镜像文件。你可以从CentOS官网下载&#xff1a;The CentOS Project 1. 安装环境准备 确保你的计算机满足CentOS 7的最低系统要求。CentOS 7支持的最低系统要求如下&#xff1a; x86-64或x86架构…

DR模式下LVS负载均衡聚集部署实验

目录 1、实验准备 2、配置负载调度器&#xff08;ens33&#xff1a;192.168.80.9 VIP:192.168.80.188&#xff09; 2.1 配置虚拟ip地址&#xff08;VIP&#xff1a;192.168.80.188&#xff09; 2.2 调整proc响应参数 2.3 设置负载分配策略 3、部署共享存储&#xff08;NF…

LeetCode1394. Find Lucky Integer in an Array

文章目录 一、题目二、题解 一、题目 Given an array of integers arr, a lucky integer is an integer that has a frequency in the array equal to its value. Return the largest lucky integer in the array. If there is no lucky integer return -1. Example 1: Inp…

【算法可视化】搜索算法专题

运行平台 Algorithm Visualizer 选数 [NOIP2002 普及组] 选数 // 导入可视化库 { const { Tracer, Array1DTracer, LogTracer, Layout, VerticalLayout } require(algorithm-visualizer); // }const N 4, K 3; //从包含4个元素的集合中选出3个数 let ans 0 //方案数 co…

static详解

前言 大家好我是jiantaoyab&#xff0c;这篇文章来谈一谈c中的static&#xff0c;根据对static的使用&#xff0c;我分为类内和类外2种情况 static简介 static是c常用的修饰符&#xff0c;它用来控制变量的存储方式和可见性&#xff0c;在变量前面加上一个static&#xff0c…

代码随想录算法训练营第五十二天 300.最长递增子序列 、674. 最长连续递增序列 、718. 最长重复子数组

代码随想录算法训练营第五十二天 | 300.最长递增子序列 、674. 最长连续递增序列 、718. 最长重复子数组 300.最长递增子序列 题目链接&#xff1a;300. 最长递增子序列 - 力扣&#xff08;LeetCode&#xff09; class Solution {public int lengthOfLIS(int[] nums) {int l…

ECMAScript 语法

ECMAScript 语法 一、ECMAScript1.ECMAScript简介2.ECMAScript历史 二、ECMAScript 语法区分大小写变量是弱类型的每行结尾的分号可有可无注释与 Java、C 和 PHP 语言的注释相同括号表示代码块 一、ECMAScript ECMAScript是一种由Ecma国际&#xff08;前身为欧洲计算机制造商协…

大唐杯学习笔记:Day6

1.1小区选择 一、概述 1.UE在RRC_IDLE和RRC——INACTIVATE状态下进行的过程&#xff1b; 2.UE首先需要完成PLMN的选择,在已选择的PLMN上寻找合适的小区,获取合适的服务,监听控制信道,这个过程即小区选择过程&#xff1b; 3.根据小区重选准则,UE寻找其他更适合的小区进行小区…