有关排序的算法

目录

选择法排序

冒泡法排序

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.xdnf.cn/news/1452796.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

不可不知的Java SE技巧:如何使用for each循环遍历数组

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

第 18章 安全架构设计理论与实践

安全架构是架构面向安全性方向上的一种细分&#xff0c;可关注三个安全方面&#xff0c;即产品安全架构、安全技术体系架构和审计架构&#xff0c;这三个方面可组成三道安全防线。本章主要分析安全威胁、介绍安全模型&#xff0c;在此基础上&#xff0c;就系统、信息、网络和数…

15.混合专家模型(MoEs)技术揭秘

混合专家模型&#xff08;MoEs&#xff09;技术揭秘 混合专家模型&#xff08;Mixture-of-Experts, MoEs&#xff09;技术发展简史 Mixtral 8x7B &#xff1a;质效并举的稀疏混合专家模型 Mixtral 8x7B &#xff1a;质效并举的稀疏混合专家模型 MoEs 技术发展简史 MoEs 开山…

如何从戴尔笔记本电脑恢复数据?

戴尔笔记本电脑上的数据存储在计算机的硬盘上。通常&#xff0c;您可以将数据安全地保存在笔记本电脑上。但是&#xff0c;戴尔笔记本电脑上的文件可能会因某些问题而丢失。例如&#xff0c;意外删除、格式化、系统升级、病毒感染、数据传输失败或其他未知问题都会导致戴尔笔记…

誉天教育近期开班计划(6月15日更新)

云计算HCIP 周末班 2024/6/15 田老师 售前IP-L3 周末班 2024/6/15 陈老师 RHCA442 晚班 2024/6/17邹老师 数通HCIE 晚班 2024/6/24阮老师 云计算HCIE直通车晚班 2024/6/25 曾老师 售前IT-L3 周末班 2024/6/29 伍老师 数通HCIP 晚班 2024/7/1杨老师 存储直通车 晚班 2024/7/1 高…

房地产房型展示信息小程序的内容是什么

地产业规模之大且品牌众多&#xff0c;还有房屋租赁、中介等&#xff0c;无论开发商公司还是衍生行业商家都需要多渠道宣传品牌和客户触达沟通转化&#xff0c;除了线下各种传单&#xff0c;线上也是主要场景&#xff0c;通过各种连接来达到相应目标。 也因此需符合平台生态开…

Qt状态机框架

概述 状态机框架提供了用于创建和执行状态图的类。这些概念和符号基于Harel的Statecharts:复杂系统的可视化形式(http://www.wisdom.weizmann.ac.il/~dharel/SCANNED.PAPERS/Statecharts.pdf)&#xff0c;也是UML状态图的基础。状态机执行的语义基于状态图XML (SCXML)(http://…

Android断点续传原理及实现

常见两种网络请求方式 一、 HttpURLConnection HttpURLConnection的setRequestProperty()方法&#xff0c;对我们要读取的字节部分进行控制&#xff0c;比如: 1.Range0-100代表只读取前100个字节。 2.Range100-500代表读取从第100个字节开始&#xff0c;读到第500个字节为止。…

【单元测试】Spring Boot 的测试库

Spring Boot 的测试库 1.了解回归测试框架 JUnit2.了解 assertThat3.了解 Mockito4.了解 JSONPath5.测试的回滚 单元测试&#xff08;unit test&#xff09;是为了检验程序的正确性。一个单元可能是单个 程序、类、对象、方法 等&#xff0c;它是应用程序的最小可测试部件。 单…

Windows10 MySQL(8.0.37)安装与配置

一、MySQL8.0.37下载 官网下载链接&#xff1a; https://dev.mysql.com/downloads/ 解压文件&#xff0c;解压到你想要的位置 二、新建MySQL配置文件 右键新建文本文档 新建my.txt文件 编辑my.txt文件&#xff0c;输入以下内容 [mysqld] # 设置 3306 端口 port3306 # 设…

STM32项目分享:智慧农业(机智云)系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.c…

[Vulnhub]Wintermute LFI+SMTP+Screen+Structv2-RCE+Lxc逃逸

概要 靶机 192.168.8.104 信息收集 $ nmap 192.168.8.103 --min-rate 1000 -sC -sV 结果: Starting Nmap 7.92 ( https://nmap.org ) at 2024-06-15 05:54 EDT Nmap scan report for 192.168.8.103 (192.168.8.103) Host is up (0.035s latency). Not shown: 997 closed t…

【LLM】吴恩达『微调大模型』课程完全笔记

Finetuning Large Language Models 版权说明&#xff1a; 『Finetuning Large Language Models』是DeepLearning.AI出品的免费课程&#xff0c;版权属于DeepLearning.AI(https://www.deeplearning.ai/)。 本文是对该课程内容的翻译整理&#xff0c;只作为教育用途&#xff0c;不…

数据结构之LinkedList与链表(上)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 手动实现单链表的源码 手动实现双链表的源码 分析 LinkedList 的源码 LinkedList的使用 …

ChatGPT关联技术

ChatGPT关联技术 一、前馈神经网络二、序列到序列模型&#xff08;Seq2Seq&#xff09;三、自注意力机制四、多头自注意力机制五、自监督学习六、Transformer模型七、语言生成技术八、多语种语言模型九、预训练语言模型十、生成式预训练模型&#xff08;GPT&#xff09;十一、近…

人民日报:高考填志愿十问十答,填报志愿时需要考虑哪些因素?

高考结束&#xff0c;志愿填报即将开始&#xff0c;填报志愿时需要考虑哪些因素&#xff1f;如何避免高分低录甚至落榜&#xff1f;高考填志愿你需要知道的事↓↓ 祝福考生考入理想大学、就读喜欢的专业。加油&#xff01; 责任编辑&#xff1a;曹继炜

【计算机网络仿真实验-实验2.6】带交换机的RIP路由协议

实验2.6 带交换机的rip路由协议 1. 实验拓扑图 2. 实验前查看是否能ping通 不能 3. 三层交换机配置 switch# configure terminal switch(config)# hostname s5750 !将交换机更名为S5750 S5750# configure terminal S5750(config)#vlan 10 S5750(config-vlan)#exit S57…

Android 工程副总裁卸任

Android 工程副总裁卸任 Android工程副总裁Dave Burke宣布&#xff0c;他将辞去领导Android工程的职位&#xff0c;将重心转向“AI/生物”项目。不过&#xff0c;他并没有离开Alphabet&#xff0c;目前仍将担任Android系统开发顾问的角色。 Burke参与了Android系统的多个关键…

偏微分方程算法之抛物型方程差分格式编程示例三(C-N格式)

目录 一、研究问题 二、C++代码 三、结果分析 一、研究问题 已知其精确解为。分别取以下三种步长: ①

随机森林算法进行预测(+调参+变量重要性)--血友病计数数据

1.读取数据 所使用的数据是血友病数据&#xff0c;如有需要&#xff0c;可在主页资源处获取&#xff0c;数据信息如下&#xff1a; import pandas as pd import numpy as np hemophilia pd.read_csv(D:/my_files/data.csv) #读取数据 2.数据预处理 在使用机器学习方法时&…