有关排序的算法

目录

选择法排序

冒泡法排序

qsort排序(快速排序)

qsort排序整型

qsort排序结构体类型


排序是我们日常生活中比较常见的问题,这里我们来说叨几个排序的算法。

比如有一个一维数组 arr[8] ={2,5,3,1,7,6,4,8},我们想要把它排成升序,我们通过下面这几种不同的方式来进行排序!

选择法排序

这一种排序方式,首先第一轮认为第一个元素是最小的,把它的下标用 flag 记下来,不断与后面的元素进行比较,如果后面的元素有比它小的,就把 flag 改成比它小的元素下标,直到把整个数组下标遍历完,如果flag不等于最开始的下标就进行交换,这样就可以得到最小的那个数在第一位,依此类推,第二轮找到第二小的数字放在第二位,第三轮找到第三小的数字放在第三位……

当第七轮的时候已经找到了找到第七小的数字放在第七位,显然最后一位是最大的数字,所以一共进行七次就好了!

代码如下:

//选择法排序
#include<stdio.h>
int main()
{int arr[8] = { 2,5,3,1,7,6,4,8 };int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;int j = 0;int flag = 0;printf("排序前:\n");for (i = 0; i < sz; i++){printf("%d ", arr[i]);}for (i = 0; i < sz - 1; i++){flag = i;for (j = i + 1; j < sz; j++){if (arr[j] < arr[flag])flag = j;//如果后面的元素比flag为坐标的元素小,就把flag改成较小元素的坐标}if (flag != i){int temp = arr[i];arr[i] = arr[flag];arr[flag] = temp}}printf("\n排序后:\n");for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

当然,在学习了指针的基础上,我们可以把排序代码分装成函数的形式


#include<stdio.h>
void Print_arr(int* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%d ", arr[i]);
}
void Choose_sort(int* arr, int sz)
{int flag = 0;for (int i = 0; i < sz - 1; i++){flag = i;for (int j = i + 1; j < sz; j++){if (arr[j] < arr[flag])flag = j;}if (flag != i){int temp = arr[i];arr[i] = arr[flag];arr[flag] = temp;}}
}
int main()
{int arr[8] = { 2,5,3,1,7,6,4,8 };int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:\n");Print_arr(arr, sz);Choose_sort(arr, sz);printf("\n排序后:\n");Print_arr(arr, sz);return 0;
}

冒泡法排序

这个与选择法排序有点相似,它的核⼼思想是两两相邻的元素进⾏⽐较,如果后面的元素比前面小,那么就立刻进行交换,第一轮最终会把最大的元素放在最后一位,依次往后面推进,在第七轮的时候,第二小的就在第二位了,所以只需要7趟就好了,每一趟就会找到一个元素放在相应的位置,所以每一趟比较的数组元素也会依次减1.

代码如下:


//冒泡排序
#include<stdio.h>
int main()
{int arr[8] = { 2,5,3,1,7,6,4,8 };int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;int j = 0;printf("排序前:\n");for (i = 0; i < sz; i++){printf("%d ", arr[i]);}for (i = 0; i < sz - 1; i++){//i代表趟数for (j = 0 ; j < sz - 1 - i; j++){//访问数组元素两两比较if ( arr[j+1]<arr[j]){int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}		}	}printf("\n排序后:\n");for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}

我们也可以把排序代码分装成函数的形式:

#include<stdio.h>
void Print_arr(int* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%d ", arr[i]);
}
void Bubble_sort(int* arr, int sz)
{int i = 0;int j = 0;for (i = 0; i < sz - 1; i++){for (j = 0; j < sz - 1 - i; j++){if (*(arr+j+1) < *(arr+j)){int temp = *(arr + j + 1);*(arr + j + 1) = *(arr + j);*(arr + j) = temp;}/*if (arr[j + 1] < arr[j]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}*/}}
}
int main()
{int arr[8] = { 2,5,3,1,7,6,4,8 };int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:\n");Print_arr(arr, sz);Bubble_sort(arr, sz);printf("\n排序后:\n");Print_arr(arr, sz);return 0;
}

我们来考虑一个问题,如果一个数组元素已经有序了,事实上,我们可以不用再进行排序了,那么应该怎么优化这个排序代码呢?

#include<stdio.h>
void Print_arr(int* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%d ", arr[i]);
}
void Bubble_sort(int* arr, int sz)
{int i = 0;int j = 0;for (i = 0; i < sz - 1; i++){int flag = 1;//最开始就假设有序for (j = 0; j < sz - 1 - i; j++){if (*(arr + j + 1) < *(arr + j)){flag = 0;//进来就说明还没有有序,让flag=0int temp = *(arr + j + 1);*(arr + j + 1) = *(arr + j);*(arr + j) = temp;}}if (flag == 1)//一趟下来flag=1,说明没有机会让flag=0,已经有序{printf("\n已经有序!\n");break;}}
}
int main()
{int arr[8] = { 1,2,3,4,5,6,7,8 };int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:\n");Print_arr(arr, sz);Bubble_sort(arr, sz);printf("\n排序后:\n");Print_arr(arr, sz);return 0;
}

这里我们就可以使用一个flag来进行标记,flag=1,就说明已经有序,跳出循环,当一个数组已经已经有序或者接近有序的时候就可以减少运算次数

qsort排序(快速排序)

想要使用qsort函数呢?我们就需要先对这个函数进行一定的了解。

打开cplusplus网站,我们可以找到相关信息:

qsort(quick sort)事实上是C语言中的一个库函数,底层使用的是快速排序的思想,

并且对任意类型数据都可以进行排序

我们来看看每一个参数

base:指向需要排序数组的首元素地址(指针)

num:base指向数组中的元素个数

size:bas指向的数组中一个元素的字节大小

compar:函数指针,传递函数的地址

compar应该设计成下面这个样子,同时它的返回值也有要求

 
int compar (const void* p1, const void* p2);

当p1指向的元素小于p2指向的元素时,返回一个小于0的数字

当p1指向的元素等于p2指向的元素时,返回0

当p1指向的元素大于p2指向的元素时,返回一个大于0的数字

qsort排序整型

//测试qsort排序整型#include<stdio.h>
#include<stdlib.h>
void Print_arr(int* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%d ", arr[i]);
}
int cmp_int(const void* p1, const void* p2)
{if (*(int*)p1 > *(int*)p2){return 1;}//知道比较整型,强制类型转换为整型,然后解引用else if (*(int*)p1 < *(int*)p2){return -1;}else{return 0;}
}
int main()
{int arr[8] = { 2,5,3,1,7,6,4,8 };int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:\n");Print_arr(arr, sz);qsort(arr, sz, sizeof(arr[0]), cmp_int);printf("\n排序后:\n");Print_arr(arr, sz);return 0;
}

我们可以看见qsort进行了很好的排序,当然这里因为它的规则是

当p1指向的元素小于p2指向的元素时,返回一个小于0的数字

当p1指向的元素等于p2指向的元素时,返回0

当p1指向的元素大于p2指向的元素时,返回一个大于0的数字

所以我们可以把return语句直接写成:

return *((int*)p1) - *((int*)p2);

#include<stdio.h>
#include<stdlib.h>
void Print_arr(int* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%d ", arr[i]);
}
int cmp_int(const void* p1, const void* p2)
{//return *((int*)p1) - *((int*)p2);//默认升序//知道比较整型,强制类型转换为整型,然后解引用return *((int*)p2) - *((int*)p1); // 降序
}
int main()
{int arr[8] = { 2,5,3,1,7,6,4,8 };int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:\n");Print_arr(arr, sz);qsort(arr, sz, sizeof(arr[0]), cmp_int);printf("\n排序后:\n");Print_arr(arr, sz);return 0;
}

使用qsort默认是升序,如果想要降序,交换p1,p2的位置就可以了,比如上面的代码就可以实现降序。

qsort排序结构体类型

//qsort排序结构体类型
#include<stdio.h>
#include<stdlib.h>//qsort头文件
#include<string.h>//strcmp头文件
struct Student
{char name[20];int age;
};
void Print_arr(struct Student* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%s %d\n", arr[i].name, arr[i].age);
}
int cmp_student_by_name(const void* p1, const void* p2)
{return strcmp(((struct Student*)p1)->name, ((struct Student*)p2)->name);//strcmp比较字符串,比较第一个不同字符的ASCII值
}
int main()
{struct Student arr[3] = { {"lihua",18},{"balla",56},{"guna",23} };//结构体数组int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:\n");Print_arr(arr, sz);qsort(arr, sz, sizeof(arr[0]), cmp_student_by_name);printf("\n排序后:\n");Print_arr(arr, sz);return 0;
}

这里依然是比较的时候强制类型转换为结构体类型,使用了结构体访问操作符【->】特殊的是比较字符串需要使用strcmp函数,不清楚的可以看看【数组的使用】那一篇博客对strcmp进行详细讲解。

我们也可以通过年龄来比较,代码如下:

#include<stdio.h>
#include<stdlib.h>//qsort头文件
//#include<string.h>//strcmp头文件
struct Student
{char name[20];int age;
};
void Print_arr(struct Student* arr, int sz)
{for (int i = 0; i < sz; i++)printf("%s %d\n", arr[i].name, arr[i].age);
}
int cmp_student_by_age(const void* p1, const void* p2)
{return (((struct Student*)p1)->age - ((struct Student*)p2)->age);
}
int main()
{struct Student arr[3] = { {"lihua",18},{"balla",56},{"guna",23} };//结构体数组int sz = sizeof(arr) / sizeof(arr[0]);printf("排序前:\n");Print_arr(arr, sz);qsort(arr, sz, sizeof(arr[0]), cmp_student_by_age);printf("\n排序后:\n");Print_arr(arr, sz);return 0;
}

当然排序算法永远不止于此,还有更多的内容等待着我们去发现,去应用。

加油吧!未来的顶尖程序员们!!!!

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

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

相关文章

StarNet实战:使用StarNet实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集 摘要 https://arxiv.org/pdf/2403.19967 论文主要集中在介绍和分析一种新兴的学习范式——星操作&#xff08;Star Operation&#xff09;&#xff0c;这是一种通过元素级乘法融合不同子…

排序-快速排序

快速排序&#xff08;Quick Sort&#xff09;是一种高效的排序算法&#xff0c;由英国计算机科学家霍尔&#xff08;C. A. R. Hoare&#xff09;在1960年提出。它的基本思想是&#xff1a;通过一趟排序将待排记录分隔成独立的两部分&#xff0c;其中一部分记录的关键字均比另一…

探究Spring Boot自动配置的底层原理

在当今的软件开发领域&#xff0c;Spring Boot已经成为了构建Java应用程序的首选框架之一。它以其简单易用的特性和强大的功能而闻名&#xff0c;其中最引人注目的特性之一就是自动配置&#xff08;Auto-Configuration&#xff09;。Spring Boot的自动配置能够极大地简化开发人…

VS2022 使用C++访问 mariadb 数据库

首先,下载 MariaDB Connector/C++ 库 MariaDB Products & Tools Downloads | MariaDB 第二步,安装后 第三步,写代码 #include <iostream> #include <cstring> #include <memory> #include <windows.h>#include <mariadb/conncpp.hpp>…

使用 Python 进行测试(6)Fake it...

总结 如果我有: # my_life_work.py def transform(param):return param * 2def check(param):return "bad" not in paramdef calculate(param):return len(param)def main(param, option):if option:param transform(param)if not check(param):raise ValueError(…

js中有哪些函数?

命名函数&#xff1a;通过function声明的函数&#xff1b; 匿名函数&#xff1a;通过函数表达式定义的函数&#xff1b; 自执行函数&#xff1a;自动执行的函数&#xff0c;不可以被调用&#xff0c;也称为一次性函数&#xff1b; 闭包函数&#xff1a;内部可以访问外部&…

winform 应用程序 添加 wpf控件后影响窗体DPI改变

第一步&#xff1a;添加 应用程序清单文件 app.manifest 第二步&#xff1a;把这段配置 注释放开&#xff0c;第一个配置true 改成false

Java——只保留一位小数

使用return Math.random(); 要将 Math.random() 的结果保留一位小数&#xff0c;您可以使用以下代码&#xff1a; double randomNumber Math.random(); double roundedNumber Math.round(randomNumber * 10.0) / 10.0; return roundedNumber; 这里的关键是将随机数乘以 …

Wifi通信协议:WEP,WPA,WPA2,WPA3,WPS

前言 无线安全性是保护互联网安全的重要因素。连接到安全性低的无线网络可能会带来安全风险&#xff0c;包括数据泄露、账号被盗以及恶意软件的安装。因此&#xff0c;利用合适的Wi-Fi安全措施是非常重要的&#xff0c;了解WEP、WPA、WPA2和WPA3等各种无线加密标准的区别也是至…

实战 | 基于YOLOv10的车辆追踪与测速实战【附源码+步骤详解】

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

go 基础笔记

文章目录 go 基础笔记Go项目依赖关系ORM&#xff08;对象关系映射&#xff09;库mysql 建库 go 基础笔记 _ "github.com/go-sql-driver/mysql"该行代码是Go语言中的导入语句&#xff0c;但带有下划线&#xff08;_&#xff09;前缀表示该包被导入但其内容不会被直接…

【单片机毕业设计选题24008】-基于单片机的寝室系统设计

系统功能: 1. 采用STM32最小系统板控制&#xff0c;将采集到温湿度光照等传感器数据显示在OLED上 2. 通过离线语音模块开关灯&#xff0c;风扇&#xff0c;门。 3. 监测到MQ2烟雾后触发报警。 4. 语音&手动&定时控制窗帘。 5. 按键开启布防模式&#xff0c;布防后…

上位机图像处理和嵌入式模块部署(h750 mcu和usb虚拟串口)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 对于mcu usb而言&#xff0c;大部分情况下&#xff0c;它和上位机之间的关系都是device的关系。一般usb&#xff0c;可以分成host和device。如果mc…

自动化测试git的使用

git是一款分布式的配置管理工具。本文主要讲git如何在自动化测试中安装&#xff0c;上传及拉取下载代码。 1 、git 介绍 每天早上到公司&#xff0c;从公司的git服务器上下载最新的代码&#xff0c;白天在最新的代码基础上&#xff0c;编写新的代码&#xff0c;下班时把“代码…

SSID简介

一、 SSID 概念定义 SSID&#xff08;Service Set Identifier&#xff09;即服务集标识符。它是无线网络中的一个重要标识&#xff0c;用于区分不同的无线网络。 相当于无线网络的名称&#xff0c;用于区分不同的无线网络。用户在众多可用网络中识别和选择特定网络的依据。通…

消息队列-消息队列保证消息可靠性的一些建议

如何检测到消息丢失&#xff1f; 美团消息队列文章中提到了对消息队列的监控手段&#xff0c;我理解消息丢失&#xff0c;根据不同节点来查看监控&#xff1a; 生产者生产丢失&#xff1a;监控中生产者生产量异常消费者消费丢失&#xff1a;查看消费者消息延迟监控、消费者 o…

新能源汽车高压上电、高压下电逻辑分析

高压上电逻辑 新能源汽车的上电分为高压上电和低压上电&#xff0c;高压上电流程一般理解为高压件通电的过程&#xff0c;具体流程如下&#xff1a; 1、点火开关处于ON档时&#xff0c;仪表盘点亮&#xff0c;低压电接通。 2、VCU、BMS、MCU等控制模块依次被唤醒并开始进行自检…

基于Java自习室在线预约系统 的设计与实现

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

解决JupyteNotebook打不开问题

问题&#xff1a;打开jupyternotebook出现黑色界面&#xff0c;马上闪退 步骤&#xff1a; 1、winr&#xff0c;cmd进入&#xff0c;conda activate yes 进入yes环境&#xff08;后面是要下载新的jupyter notebook&#xff09;,我这里下载到了yes环境下 2、下载jupyter Note…

<Rust><iced>基于rust使用iced库构建GUI实例:图片的格式转换程序

前言 本专栏是Rust实例应用。 环境配置 平台&#xff1a;windows 软件&#xff1a;vscode 语言&#xff1a;rust 库&#xff1a;iced、iced_aw 概述 本文是专栏第二篇实例&#xff0c;是一个图像格式转换程序&#xff0c;基于rust图像处理库image以及文件处理库rfd。 UI演示&…