当前位置: 首页 > news >正文

使用冒泡排序模拟实现qsort函数

1.冒泡排序

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>int main()
{int arr[] = { 0,2,5,3,4,8,9,7,6,1 };int sz = sizeof(arr) / sizeof(arr[0]);//冒泡排序一共排序 sz-1 趟for (int i = 0; i < sz - 1; ++i){//标志位,如果有序,直接退出int flag = 0;//第一趟比较sz-1次,//以后每趟比较次数-1for (int j = 0; j < sz - 1 - i; ++j){if (arr[j] > arr[j + 1]){flag = 1;int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}if (!flag)break;}for (int i = 0; i < sz; ++i)printf("%d ", arr[i]);return 0;
}

2.模拟实现

2.1认清障碍

qsort函数可以实现任意数据的排序

但此时的冒泡排序不行,阻碍点:

(1)

冒泡排序中 if 条件判断中的 >

注定了该算法不能实现其他数据的比较

想到:

模仿qsort函数,在冒泡排序内部

调用相关函数实现数据比较

然后根据调用函数的返回值进行后续操作

(2)

上面的交换方式也受到了限制

想到:

需要实现一个

可以实现数据交换的函数

2.2克服障碍

2.2.1依葫芦画瓢

 那就依葫芦画瓢,写下声明

void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2));

此时:

从左往右,要传入的

第一个参数是 待排序数组的第一个元素的地址

 第二个参数是 元素个数

第三个参数是 每个元素的大小,单位是字节

第四个参数是 一个函数指针

Bubble_sort函数通过这个函数指针调用相关的函数

被调用的函数就是用来实现任意数据的比较方式的

被调用的函数:

返回值为int,形参为(const void*p1,const void*p2)

(1

p1指向一个数组元素

p2指向的是p1指向的元素之后的第一个元素

(2)函数内部的要求:

(2.1)void*不能直接解引用或+-整数操作

所以需要根据需求进行相应的显式类型转换

(2.2)显示类型转换后,

当p1指向的内容大于p2时,函数返回 大于0的值

当p1指向的内容小于p2时,函数返回 大于0的值

当p1指向的内容等于p2时,函数返回 0

2.2.2逐步实现

void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2))
{for (int i = 0; i < num - 1; ++i){int flag = 0;for (int j = 0; j < num - 1 - i; ++j){if(){}}if (!flag)break;}
}

冒牌排序外壳:

趟数、比较次数不用改变

2.2.2.1条件判断

if 语句中,根据函数调用返回值进行判断

假设,当当p1指向的内容大于p2时,才进行数据的交换

那么,代码如下:

void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2))
{for (int i = 0; i < num - 1; ++i){int flag = 0;for (int j = 0; j < num - 1 - i; ++j){if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0){flag = 1;..}}if (!flag)break;}
}

详细解释:

(1)绿色方框框起来的意思是

(1.1)这是两个实参

(1.2)指针指向一种数据时,

总是指向该数据所占空间地址最小的那个字节

(1.3)base接收了数组首元素的地址,但是

我并不知道这是整型、浮点型、字符型的数组

所以我将它强制转换为(char*)类型的指针

这样,无论如何

(char*)base 都指向了数组首元素的第一个字节

(1.4)函数传参传进了width,

注意到:

如果是一个int型的数组

(char*)base 指向了数组首元素第一个字节

(char*)base+width指向了数组第二个元素第一个字节

(char*)base+2*width指向了数组第三个元素的第一个字节

如果是一个char型的数组

(char*)base 指向了数组首元素

(char*)base+width指向了数组第二个元素

(char*)base+2*width指向了数组第三个元素

所以:

实参就是

((char*)base+j*width,(char*)base+(j+1)*width)

(2)橙色方框框起来的意思是

调用cmp函数

(3)红色方框框起来的意思是

当cmp函数返回值>0时,才进行后续的操作

2.2.2.2交换方式

避免代码冗余,创建一个Swap函数进行数据的交换

void Bubble_sort(void*base,size_t num,size_t width,int(*cmp)(const void*p1,const void*p2))
{for (int i = 0; i < num - 1; ++i){int flag = 0;for (int j = 0; j < num - 1 - i; ++j){if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0){flag = 1;Swap((char*)base+j*width,(char*)base+(j+1)*width, width);}}if (!flag)break;}
}

(1)我们并不知道元素的类型

但是因为我们知道元素的大小

所以我们可以逐字节地交换两个元素

(2)此时,传入的参数应该是

两个元素的第一个字节、元素的大小

 Swap((char*)base+j*width,(char*)base+(j+1)*width, width);

内部实现:

void Swap(char* p1, char* p2, size_t width)
{for (int i = 0; i < width; ++i){char temp = *p1;*p1 = *p2;*p2 = temp;p1++;p2++;}
}

(1)width有多大,就交换几次

每次交换后,指针偏移

2.3测试

使用Bubble_sort函数与使用qsort函数一样

需要自己编写一个实现数据比较地函数

这是整型数据的比较

这是字符间的排序 :

注意,元素个数用strlen求!

这是字符串间的排序:

相关文章:

使用冒泡排序模拟实现qsort函数

1.冒泡排序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int arr[] { 0,2,5,3,4,8,9,7,6,1 };int sz sizeof(arr) / sizeof(arr[0]);//冒泡排序一共排序 sz-1 趟for (int i 0; i < sz - 1; i){//标志位&#xff0c;如果有序&#xff0c;直接…...

AI大模型开发原理篇-4:神经概率语言模型NPLM

神经概率语言模型&#xff08;NPLM&#xff09;概述 神经概率语言模型&#xff08;Neural Probabilistic Language Model, NPLM&#xff09; 是一种基于神经网络的语言建模方法&#xff0c;它将传统的语言模型和神经网络结合在一起&#xff0c;能够更好地捕捉语言中的复杂规律…...

Eigen::Tensor使用帮助

0 引言 用python实现了某些算法之后&#xff0c;想转成C来获取更高的性能。但是python数组的操作太灵活了&#xff0c;尤其是3维、4维、5维等高维数组&#xff0c;以及它们的广播、数组坐标、切片等机制。还有numpy的pad、where等操作更是给C转换带来了更多的麻烦。 查阅了相…...

git基础使用--3---git安装和基本使用

文章目录 git基础使用--3--git-安装和基本使用1. git工具安装1.1 git1.2 TortoiseGit1.3 远程仓2. git本地仓库版本管理2.1 git常用命令2.2 git基本操作2.2.1 设置用户名和邮箱 2.2 git基本操作2.2.1 初始化本地仓 git init2.2.2 查看本地库状态 git status2.2.3 添加暂缓区2.2…...

html的字符实体和颜色表示

在HTML中&#xff0c;颜色可以通过以下几种方式表示&#xff0c;以下是具体的示例&#xff1a; 1. 十六进制颜色代码 十六进制颜色代码以#开头&#xff0c;后面跟随6个字符&#xff0c;每两个字符分别表示红色、绿色和蓝色的强度。例如&#xff1a; • #FF0000&#xff1a;纯红…...

OpenAI发布o3-mini:免费推理模型,DeepSeek引发的反思

引言 在人工智能领域&#xff0c;OpenAI再次引领潮流&#xff0c;推出了全新的推理模型系列——o3-mini。这一系列包括low、medium和high三个版本&#xff0c;旨在进一步推动低成本推理的发展。与此同时&#xff0c;OpenAI的CEO奥特曼也在Reddit的“有问必答”活动中罕见地公开…...

Zemax 中带有体素探测器的激光谐振腔

激光谐振腔是激光系统的基本组成部分&#xff0c;在光的放大和相干激光辐射的产生中起着至关重要的作用。 激光腔由两个放置在光学谐振器两端的镜子组成。一个镜子反射率高&#xff08;后镜&#xff09;&#xff0c;而另一个镜子部分透明&#xff08;输出耦合器&#xff09;。…...

大模型训练(5):Zero Redundancy Optimizer(ZeRO零冗余优化器)

0 英文缩写 Large Language Model&#xff08;LLM&#xff09;大型语言模型Data Parallelism&#xff08;DP&#xff09;数据并行Distributed Data Parallelism&#xff08;DDP&#xff09;分布式数据并行Zero Redundancy Optimizer&#xff08;ZeRO&#xff09;零冗余优化器 …...

C# 实现 “Hello World” 教程

.NET学习资料 .NET学习资料 .NET学习资料 C# 作为一种广泛应用于.NET 开发的编程语言&#xff0c;以其简洁、高效和类型安全等特性&#xff0c;深受开发者喜爱。在踏入 C# 编程领域时&#xff0c;编写经典的 “Hello World” 程序是重要的起点&#xff0c;它能帮助我们快速熟…...

LabVIEW无线齿轮监测系统

本案例介绍了基于LabVIEW的无线齿轮监测系统设计。该系统利用LabVIEW编程语言和改进的天牛须算法优化支持向量机&#xff0c;实现了无线齿轮故障监测。通过LabVIEW软件和相关硬件&#xff0c;可以实现对齿轮箱振动信号的采集、传输和故障识别&#xff0c;集远程采集、数据库存储…...

IM 即时通讯系统-01-概览

前言 有时候希望有一个 IM 工具&#xff0c;比如日常聊天&#xff0c;或者接受报警信息。 其实主要是工作使用&#xff0c;如果是接收报警等场景&#xff0c;其实DD这种比较符合场景。 那么有没有必要再创造一个DD呢&#xff1f; 答案是如果处于个人的私有化使用&#xff0…...

【人工智能】 在本地运行 DeepSeek 模型:Ollama 安装指南

持续更新。。。。。。。。。。。。。。。 【人工智能】 在本地运行 DeepSeek 模型&#xff1a;Ollama 安装指南 安装 Ollama安装 DeepSeek 模型选择版本 &#xff0c;版本越高&#xff0c;参数越多 性能越好使用 DeepSeek 模型 安装 Ollama 访问 Ollama 官网: 前往 https://oll…...

【Linux系统】信号:信号保存 / 信号处理、内核态 / 用户态、操作系统运行原理(中断)

理解Linux系统内进程信号的整个流程可分为&#xff1a; 信号产生 信号保存 信号处理 上篇文章重点讲解了 信号的产生&#xff0c;本文会讲解信号的保存和信号处理相关的概念和操作&#xff1a; 两种信号默认处理 1、信号处理之忽略 ::signal(2, SIG_IGN); // ignore: 忽略#…...

探索 Copilot:开启智能助手新时代

探索 Copilot&#xff1a;开启智能助手新时代 在当今数字化飞速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变着我们的工作和生活方式。而 Copilot 作为一款强大的 AI 助手&#xff0c;凭借其多样的功能和高效的应用&#xff0c;正在成为众…...

解锁豆瓣高清海报(二) 使用 OpenCV 拼接和压缩

解锁豆瓣高清海报(二): 使用 OpenCV 拼接和压缩 脚本地址: 项目地址: Gazer PixelWeaver.py pixel_squeezer_cv2.py 前瞻 继上一篇“解锁豆瓣高清海报(一) 深度爬虫与requests进阶之路”成功爬取豆瓣电影海报之后&#xff0c;本文将介绍如何使用 OpenCV 对这些海报进行智…...

我用Ai学Android Jetpack Compose之Card

这篇学习一下Card。回答来自 通义千问。 我想学习Card&#xff0c;麻烦你介绍一下 当然可以&#xff01;在 Jetpack Compose 中&#xff0c;Card 是一个非常常用的组件&#xff0c;用于创建带有阴影和圆角的卡片式布局。它可以帮助你轻松实现美观且一致的 UI 设计&#xff0c…...

NLP深度学习 DAY4:Word2Vec详解:两种模式(CBOW与Skip-gram)

用稀疏向量表示文本&#xff0c;即所谓的词袋模型在 NLP 有着悠久的历史。正如上文中介绍的&#xff0c;早在 2001年就开始使用密集向量表示词或词嵌入。Mikolov等人在2013年提出的创新技术是通过去除隐藏层&#xff0c;逼近目标&#xff0c;进而使这些单词嵌入的训练更加高效。…...

论文阅读(十):用可分解图模型模拟连锁不平衡

1.论文链接&#xff1a;Modeling Linkage Disequilibrium with Decomposable Graphical Models 摘要&#xff1a; 本章介绍了使用可分解的图形模型&#xff08;DGMs&#xff09;表示遗传数据&#xff0c;或连锁不平衡&#xff08;LD&#xff09;&#xff0c;各种下游应用程序之…...

Python中容器类型的数据(上)

若我们想将多个数据打包并且统一管理&#xff0c;应该怎么办? Python内置的数据类型如序列(列表、元组等)、集合和字典等可以容纳多项数据&#xff0c;我们称它们为容器类型的数据。 序列 序列 (sequence) 是一种可迭代的、元素有序的容器类型的数据。 序列包括列表 (list)…...

PySPARK带多组参数和标签的SparkSQL批量数据导出到S3的程序

设计一个基于多个带标签SparkSQL模板作为配置文件和多组参数的PySPARK代码程序&#xff0c;实现根据不同的输入参数自动批量地将数据导出为Parquet、CSV和Excel文件到S3上&#xff0c;标签和多个参数&#xff08;以“_”分割&#xff09;为组成导出数据文件名&#xff0c;文件已…...

蓝桥杯备考:模拟算法之字符串展开

P1098 [NOIP 2007 提高组] 字符串的展开 - 洛谷 | 计算机科学教育新生态 #include <iostream> #include <cctype> #include <algorithm> using namespace std; int p1,p2,p3; string s,ret; void add(char left,char right) {string tmp;for(char ch left1;…...

使用LLaMA-Factory对AI进行认知的微调

使用LLaMA-Factory对AI进行认知的微调 引言1. 安装LLaMA-Factory1.1. 克隆仓库1.2. 创建虚拟环境1.3. 安装LLaMA-Factory1.4. 验证 2. 准备数据2.1. 创建数据集2.2. 更新数据集信息 3. 启动LLaMA-Factory4. 进行微调4.1. 设置模型4.2. 预览数据集4.3. 设置学习率等参数4.4. 预览…...

@Nullable 注解

文章目录 解释 Nullable 注解注解的组成部分&#xff1a;如何使用 Nullable 注解a. 标注方法返回值&#xff1a;b. 标注方法参数&#xff1a;c. 标注字段&#xff1a; 结合其他工具与 Nonnull 配合使用总结 Nullable 注解在 Java 中的使用场景通常与 Nullability&#xff08;空…...

Arduino大师练成手册 -- 控制 AS608 指纹识别模块

要在 Arduino 上控制 AS608 指纹识别模块&#xff0c;你可以按照以下步骤进行&#xff1a; 硬件连接 连接指纹模块&#xff1a;将 AS608 指纹模块与 Arduino 连接。通常&#xff0c;AS608 使用 UART 接口进行通信。你需要将 AS608 的 TX、RX、VCC 和 GND 引脚分别连接到 Ardu…...

Mask R-CNN与YOLOv8的区别

Mask R-CNN与YOLOv8虽然都是深度学习在计算机视觉领域的应用&#xff0c;但它们属于不同类型的视觉框架&#xff0c;各有特点和优势。 以下是关于 Mask R-CNN 和 YOLOv8 的详细对比分析&#xff0c;涵盖核心原理、性能差异、应用场景和选择建议&#xff1a; 1. 核心原理与功能…...

在Ubuntu上使用Docker部署DeepSeek

在Ubuntu上使用Docker部署DeepSeek&#xff0c;并确保其可以访问公网网址进行对话&#xff0c;可以按照以下步骤进行&#xff1a; 一、安装Docker 更新Ubuntu的软件包索引&#xff1a; sudo apt-get update安装必要的软件包&#xff0c;这些软件包允许apt通过HTTPS使用存储库…...

MySQL的覆盖索引

MySQL的覆盖索引 前言 当一个索引包含了查询所需的全部字段时&#xff0c;就可以提高查询效率&#xff0c;这样的索引又被称之为覆盖索引。 以MySQL常见的三种存储引擎为例&#xff1a;InnoDB、MyISAM、Memory&#xff0c;对于覆盖索引提高查询效率的方式均不同&#xff0c;…...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.12 连续数组:为什么contiguous这么重要?

2.12 连续数组&#xff1a;为什么contiguous这么重要&#xff1f; 目录 #mermaid-svg-wxhozKbHdFIldAkj {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-wxhozKbHdFIldAkj .error-icon{fill:#552222;}#mermaid-svg-…...

在React中使用redux

一、首先安装两个插件 1.Redux Toolkit 2.react-redux 第一步&#xff1a;创建模块counterStore 第二步&#xff1a;在store的入口文件进行子模块的导入组合 第三步&#xff1a;在index.js中进行store的全局注入 第四步&#xff1a;在组件中进行使用 第五步&#xff1a;在组件中…...

lstm预测

import numpy as np import pandas as pd import tensorflow as tf import math import matplotlib.pyplot as plt from sklearn.preprocessing import MinMaxScaler from keras.layers import LSTM,Activation,Dense,Dropout# 时间序列数据转换为监督学习的格式 def creatXY(d…...