C/C++ 常见数组排序算法

本文介绍了几种常见的排序算法的实现,包括冒泡排序、选择排序、插入排序、希尔排序、归并排序和快速排序。冒泡排序通过多次遍历数组,比较并交换相邻元素,逐步将较小元素“浮”到数组顶端,时间复杂度为O(n^2)。选择排序通过选择未排序部分的最小元素进行交换,逐步完成整个数组排序,同样具有O(n^2)的时间复杂度。插入排序将数组分为已排序和未排序部分,逐个插入未排序元素到已排序部分的合适位置,时间复杂度为O(n^2)。希尔排序是插入排序的改进版本,通过分组插入排序,最终得到有序数组,时间复杂度在O(n log n)O(n^2)之间。归并排序采用分治策略,递归拆分和合并数组,时间复杂度始终为O(n log n),但需要额外空间。最后,快速排序通过选择基准值划分数组,并递归排序子数组,平均时间复杂度为O(n log n),但最坏情况下为O(n^2)。这些算法各有特点,适用于不同场景。

冒泡排序算法

冒泡排序(Bubble Sort)算法,冒泡排序是一种简单的排序算法,它多次遍历待排序的元素,依次比较相邻的两个元素,若顺序不对则交换它们,直到整个序列有序。算法的名字源于越小的元素会经过交换“浮”到数组的顶端。

这里的BubbleSort函数接受一个整数数组 Array 和数组的大小 ArraySize 作为参数,然后对该数组进行升序排序。排序过程采用嵌套的两个循环,外层循环(x 循环)控制每一轮的遍历,内层循环(y 循环)用于比较相邻元素并进行交换。

具体实现步骤:

  • 外层循环(x 循环)遍历数组,从数组的第一个元素到倒数第二个元素。
  • 内层循环(y 循环)从数组的最后一个元素向前遍历到当前外层循环位置。
  • 比较相邻的两个元素,若前一个元素大于后一个元素,则交换它们的位置,确保较小的元素“浮”到数组的顶端。
  • 重复进行步骤 1-3,直到整个数组有序。

这种排序算法的时间复杂度为 O(n^2),其中 n 是数组的大小。虽然冒泡排序不是最有效的排序算法,但它简单易懂,适用于小型数据集或部分有序的数据。在实际应用中,对于大型数据集,通常会选择更高效的排序算法,如快速排序或归并排序。

#include <stdio.h>void BubbleSort(int Array[], int ArraySize)
{int x, y, temporary;for (x = 0; x < ArraySize - 1; x++){for (y = ArraySize - 1; y > x; y--){if (Array[y-1] > Array[y]){temporary = Array[y-1];Array[y-1] = Array[y];Array[y] = temporary;}}}
}int main(int argc, char* argv[])
{int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 };BubbleSort(a, 10);for (int i = 0; i < 10; i++){printf("%d ", a[i]);}system("pause");return 0;
}

选择排序算法

选择排序(Selection Sort)算法,选择排序是一种简单直观的排序算法。它的基本思想是通过不断选择数组中未排序部分的最小元素,并将其与未排序部分的第一个元素交换位置,从而逐步完成整个数组的排序。

具体步骤如下:

  • 初始化: 遍历整个数组,假设当前位置为最小值的位置(minimum)为起始位置。
  • 查找最小值: 在未排序的部分中,从当前位置的下一个元素开始,找到比当前最小值更小的元素的位置。
  • 更新最小值位置: 如果找到了比当前最小值更小的元素,更新最小值位置(minimum)。
  • 交换操作: 在一次遍历结束后,将最小值位置的元素与当前位置的元素进行交换。
  • 迭代: 重复以上步骤,缩小未排序部分的范围,直到整个数组排序完成。

选择排序的主要特点是不涉及大量的数据移动,但由于其时间复杂度为O(n^2),在大规模数据集上性能较差。

#include <stdio.h>void SelectSort(int Array[], int ArraySize)
{int x, y, minimum, temporary;for (x = 0; x < ArraySize - 1; x++){minimum = x;   // 假设x是最小的数for (y = x + 1; y < ArraySize; y++){  // 将假设中的最小值进行比对if (Array[y] < Array[minimum])minimum = y;}if (minimum != x){ // 循环结束后进行交换temporary = Array[minimum];Array[minimum] = Array[x];Array[x] = temporary;}}
}int main(int argc, char* argv[])
{int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 };SelectSort(a, 10);for (int i = 0; i < 10; i++){printf("%d ", a[i]);}system("pause");return 0;
}

直接插入排序

插入排序(Insertion Sort)算法,插入排序是一种简单直观的排序算法,其基本思想是将数组分为已排序和未排序两部分,逐个将未排序部分的元素插入到已排序部分的合适位置。

具体步骤如下:

  • 初始化: 数组的第一个元素被认为是已排序部分,从数组的第二个元素开始,将其视为未排序部分。
  • 逐个插入: 遍历未排序部分的元素,逐个将其插入到已排序部分的合适位置。
  • 如果当前元素小于前一个已排序元素,将其与前一个元素交换,并继续向前比较,直到找到合适的位置。
  • 插入完成后,已排序部分的元素增加一个,未排序部分的元素减少一个。
  • 重复: 重复以上步骤,直到未排序部分为空,整个数组排序完成。

插入排序是一种稳定的排序算法,对于小型数据集或已经基本有序的数据集,性能较好。插入排序的平均时间复杂度为O(n^2),适用于小规模数据排序。

#include <stdio.h>void InsertSort(int Array[], int ArraySize)
{int x, y, temporary;for (x = 1; x < ArraySize; x++){if (Array[x] < Array[x - 1]){temporary = Array[x];  // 把小的元素放入tempfor (y = x - 1; Array[y] > temporary; y--){Array[y + 1] = Array[y];}Array[y + 1] = temporary;}}
}int main(int argc, char* argv[])
{int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 };InsertSort(a, 10);for (int i = 0; i < 10; i++){printf("%d ", a[i]);}system("pause");return 0;
}

希尔分组排序

希尔排序(Shell Sort)算法,希尔排序是一种改进的插入排序算法,其基本思想是通过将数组分成若干个子序列进行插入排序,逐渐缩小子序列的间隔,最终使整个数组成为一个有序序列。

具体步骤如下:

  • 确定间隔序列: 选择一个初始间隔,通常为数组长度的一半,然后逐步减小间隔。在这个实现中,间隔的更新规则是 interval = interval / 3 + 1。
  • 按间隔进行插入排序: 对每个间隔进行插入排序,即将间隔作为新的数组的步长,对每个子序列进行插入排序。
  • 重复直到排序完成: 重复以上步骤,不断缩小间隔,直到间隔为1,完成最后一次插入排序,使得整个数组有序。

希尔排序的时间复杂度受到间隔序列的选择影响,通常平均时间复杂度在O(n log n)O(n^2)之间。希尔排序相对于插入排序来说,在处理中等规模数据时性能较好。

#include <stdio.h>void ShellSort(int Array[], int ArraySize)
{int x, y, temporary;int interval = ArraySize;   // 设置排序间隔do{interval = interval / 3 + 1;for (x = interval; x < ArraySize; x++){if (Array[x] < Array[x - interval]){temporary = Array[x];  // 把小的元素放入tempfor (y = x - interval; Array[y] > temporary; y -= interval){Array[y + interval] = Array[y];}Array[y + interval] = temporary;}}} while (interval > 1);
}int main(int argc, char* argv[])
{int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 };ShellSort(a, 10);for (int i = 0; i < 10; i++){printf("%d ", a[i]);}system("pause");return 0;
}

归并排序算法

归并排序(Merge Sort)算法,归并排序是一种分治算法,其基本思想是将数组分成两个部分,对每个部分进行递归排序,然后将两个有序的子数组合并成一个有序数组。

具体步骤如下:

  • 拆分数组: 将待排序的数组分成两个子数组,分别对左右两个子数组进行递归排序。这一步骤递归执行,直到每个子数组的大小为1。
  • 归并操作: 将两个有序的子数组合并成一个有序数组。合并过程中,比较两个子数组的元素,将较小的元素放入临时数组中,直到其中一个子数组的元素全部放入临时数组中。然后将另一个未空的子数组的剩余元素直接放入临时数组。
  • 存储结果: 最后将归并得到的有序数组存储回原始数组中。

归并排序的时间复杂度始终为O(n log n),并且具有稳定性,但相对于其他排序算法,归并排序需要额外的空间来存储临时数组。

#include <stdio.h>
#define MAXSIZE 10// 实现归并,并把最后的结果存放到list1里面
void merging(int *list1,int list1_size,int *list2,int list2_size)
{int list1_sub = 0, list2_sub = 0, k = 0;int temporary[MAXSIZE];while (list1_sub < list1_size && list2_sub < list2_size){if (list1[list1_sub] < list2[list2_sub])temporary[k++] = list1[list1_sub++];elsetemporary[k++] = list2[list2_sub++];}while (list1_sub < list1_size)temporary[k++] = list1[list1_sub++];while (list2_sub < list2_size)temporary[k++] = list2[list2_sub++];// 最后将归并后的结果存入到list1变量中for (int m = 0; m < (list1_size + list2_size); m++)list1[m] = temporary[m];
}// 拆分数组,拆分以后传入merging函数实现归并
void MergeSort(int Array[], int ArraySize)
{   // 如果大于1则终止拆解数组if (ArraySize > 1){int *list1 = Array;                // 左边部分int list1_size = ArraySize / 2;    // 左边的尺寸,每次是n/2一半int *list2 = Array + ArraySize / 2;       // 右半部分,就是左半部分的地址加上右半部分的尺寸int list2_size = ArraySize - list1_size;  // 右半部分尺寸MergeSort(list1, list1_size);   // 递归拆解数组1MergeSort(list2, list2_size);   // 递归拆解数组2merging(list1, list1_size, list2, list2_size);  // 归并}
}int main(int argc, char* argv[])
{int a[10] = { 2, 5, 6, 8, 2, 3, 9, 1, 8, 0 };MergeSort(a, 10);for (int i = 0; i < 10; i++)printf("%d ", a[i]);system("pause");return 0;
}

快速排序算法

快速排序(Quick Sort)算法,快速排序是一种分治算法,其基本思想是选择数组中的一个元素作为基准值,然后将数组划分为两个子数组,一个子数组中的元素都小于基准值,另一个子数组中的元素都大于基准值。对这两个子数组进行递归排序,最终得到有序数组。

具体步骤如下:

  • 选择基准值: 从数组中选择一个元素作为基准值(这里选择第一个元素s[0])。
  • 划分数组: 设定两个指针i和j,i指向数组的起始位置,j指向数组的结束位置。通过移动指针i和j,将数组划分为两个部分,保证左边的元素小于等于基准值,右边的元素大于等于基准值。
  • 递归排序: 对划分出的两个部分分别递归进行快速排序。
  • 合并结果: 递归过程中,每个部分都会被排序,最终得到完整的有序数组。

快速排序是一种高效的排序算法,平均时间复杂度为O(n log n),但最坏情况下可能达到O(n^2)。在实际应用中,通常表现优秀。

#include <stdio.h>void QuckSort(int s[], int start, int end)
{int i, j;i = start;j = end;s[0] = s[start];            //设置基准值while (i<j){while (i<j&&s[0]<s[j])j--;                // 位置左移if (i<j){s[i] = s[j];        // 将s[j]放到s[i]的位置上i++;                // 位置右移}while (i<j&&s[i] <= s[0])i++;                 // 位置右移if (i<j){s[j] = s[i];        // 将大于基准值的s[j]放到s[i]位置j--;                // 位置右移}}s[i] = s[0];                      // 将基准值放入指定位置if (start<i)QuckSort(s, start, j - 1);    // 对分隔出的部分递归调用函数qusort()if (i<end)QuckSort(s, j + 1, end);
}int main(int argc, char *argv[])
{int Array[11] = { 4, 6, 7, 8, 2, 1, 4, 5, 5, 0 };QuckSort(Array, 0, 10);for (int x = 0; x < 10; x++){printf("%d ", Array[x]);}getchar();return 0;
}

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

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

相关文章

基于springboot实现在线外卖平台系统项目【项目源码】

基于springboot实现在线外卖平台管理系统演示 Java技术 Java是由SUN公司推出&#xff0c;该公司于2010年被oracle公司收购。Java本是印度尼西亚的一个叫做爪洼岛的英文名称&#xff0c;也因此得来java是一杯正冒着热气咖啡的标识。Java语言在移动互联网的大背景下具备了显著的…

ElasticSearch 同步的方式

ElasticSearch 同步的方式 ElasticSearch是一款强大的分布式搜索和分析引擎&#xff0c;支持多种方式同步数据和日志。下面介绍几种常见的同步方式&#xff1a; 1. Logstash Logstash 是 ElasticStack 的一部分&#xff0c;用于收集、处理和转发日志和事件数据。通过配置 Lo…

运动耳机哪个牌子好?盘点最值得入手的五款运动耳机

现在&#xff0c;不入耳的运动耳机成了许多运动爱好者的首选&#xff0c;我也不例外&#xff0c;不得不说骨传导耳机跟运动真的很搭&#xff0c;不仅佩戴稳固不掉落&#xff0c;而且防水好&#xff0c;可以说是最值得入手的运动耳机&#xff0c;为了避免大家在选购运动耳机的时…

电脑磁盘怎么设置密码?磁盘加密软件哪个好?

电脑磁盘经常被用于存放各种重要数据&#xff0c;而为了避免数据泄露&#xff0c;我们需要为磁盘设置密码&#xff0c;以防止未授权人员使用磁盘。那么&#xff0c;电脑磁盘怎么设置密码呢&#xff1f;下面我们就一起来了解一下。 如何设置磁盘密码&#xff1f; 想要为磁盘设置…

计算机毕业设计项目选题推荐(免费领源码)java+springboot+mysql社区团购APP 02043

目录 摘要 1 绪论 1.1 研究背景 1.2国内外研究现状 1.3本课题主要工作 1.4论文结构与章节安排 2 社区团购系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.…

简于外 强于内,联想全新ThinkCentre M90a Pro Gen4以强劲性能开启商

近日&#xff0c;联想发布了最新一代商用台式一体机联想ThinkCentre M90a Pro Gen4。作为联想ThinkCentre M大师系列的旗舰产品&#xff0c;其配备了优质的显示屏&#xff0c;拥有强大的性能和稳定安全的特性&#xff0c;能够满足多样的工作场合&#xff0c;为商用一体机的行业…

Java核心知识点整理大全6-笔记

目录 4.1.4. 线程生命周期(状态) 4.1.4.1. 新建状态&#xff08;NEW&#xff09; 4.1.4.2. 就绪状态&#xff08;RUNNABLE&#xff09;&#xff1a; 4.1.4.3. 运行状态&#xff08;RUNNING&#xff09;&#xff1a; 4.1.4.4. 阻塞状态&#xff08;BLOCKED&#xff09;&#xff…

五、程序员指南:数据平面开发套件

服务质量 (QoS) 框架 本章介绍 DPDK 服务质量 (QoS) 框架。 21.1 带有 QoS 支持的数据包流水线 下图显示了一个具有 QoS 支持的复杂数据包处理流水线的示例 表21.1&#xff1a;带有 QoS 支持的复杂数据包处理流水线 这个流水线可以使用可重用的 DPDK 软件库构建。在这个流…

Java注解

文章目录 java注解概述注解原理是什么注解的作用&#xff1a;java注解的分类系统注解元注解自定义注解 Java常用注解Spring Web MVC 注解Spring Bean 注解Spring Boot注解Jpa全局异常处理SpringCloud容器配置注解Spring DI注解配置注解mybatis注解 java注解概述 注解&#xff…

【工具】java判断某个时间是否在时间范围区间内

【工具】java判断某个时间是否在时间范围区间内 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public class Example {public static void main(String[] args) throws ParseException {// 要判断的时间String timeString &qu…

HarmonyOS ArkTS语言,运行Hello World(一)

一、下载与安装DevEco Studio 在HarmonyOS应用开发学习之前&#xff0c;需要进行一些准备工作&#xff0c;首先需要完成开发工具DevEco Studio的下载与安装以及环境配置。 进入DevEco Studio下载官网&#xff0c;单击“立即下载”进入下载页面。 DevEco Studio提供了Windows…

【前端学java】java中的包装类(11)

往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学 java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类的使用 &#xff08…

【深度学习】不用Conda在PP飞桨Al Studio三个步骤安装永久PyTorch环境

在 PaddlePaddle AI Studio 中使用 Python 虚拟环境安装 PyTorch 免责声明 在阅读和实践本文提供的内容之前&#xff0c;请注意以下免责声明&#xff1a; 侵权问题: 本文提供的信息仅供学习参考&#xff0c;不用做任何商业用途&#xff0c;如造成侵权&#xff0c;请私信我&am…

OpenAI董事会秒反悔!奥特曼被求重返CEO职位

明敏 丰色 发自 凹非寺 量子位 | 公众号 QbitAI 1天时间&#xff0c;OpenAI董事会大变脸。 最新消息&#xff0c;他们意在让奥特曼重返CEO职位。 多方消息显示&#xff0c;因为“投资人的怒火”&#xff0c;OpenAI董事会才在一天时间里来了个大反转。 微软CEO纳德拉被曝在得…

【nlp】2.8 注意力机制拓展

注意力机制拓展 1 注意力机制原理1.1 注意力机制示意图1.2 Attention计算过程1.3 Attention计算逻辑1.4 有无attention模型对比1.4.1 无attention机制的模型1.4.2 有attention机制的模型1 注意力机制原理 1.1 注意力机制示意图 Attention机制的工作原理并不复杂,我们可以用下…

springBoot整合quartz定时任务

声明 Quartz是一种基于java实现的任务调度框架&#xff0c;可以定时自动的执行你想要执行的任何任务。 官网&#xff1a;quartz官网 利用Quartz的定时任务技术可以应用于许多不同的场景&#xff0c;帮助我们实现定时执行任务、数据清理、缓存刷新、邮件发送、数据备份、系统监…

【Redis篇】简述Java中操作Redis的方法

文章目录 &#x1f384;简述Jedis&#x1f384;Jedis优点&#x1f354;使用Jedis连接Redis⭐进行测试&#x1f388;进行测试 Redis&#xff08;Remote Dictionary Server&#xff09;是一种流行的高性能内存数据库&#xff0c;广泛应用于各种应用程序和系统中。作为Java开发人员…

【giszz笔记】产品设计标准流程【7】

&#xff08;续上回&#xff09; 今天来讨论下产品设计标准流程中&#xff0c;交互设计和视觉设计的内容。 想参考之前文章的&#xff0c;我把链接给到这里。 【giszz笔记】产品设计标准流程【6】-CSDN博客 【giszz笔记】产品设计标准流程【5】-CSDN博客 【giszz笔记】产品…

js双击修改元素内容并提交到后端封装实现

前面发过一个版本了&#xff0c;后来又追加了些功能。重新发一版。新版支持select和radio。 效果图&#xff1a; 右上角带有绿标的&#xff0c;是可以修改的单元格。如果不喜欢显示绿标&#xff0c;可以传递参数时指定不显示&#xff0c;如果想改为其它颜色&#xff0c;也可以…

涉密人员离职怎么做好安全管理?

在信息安全领域&#xff0c;涉密人员的离职安全管理具有极其重要的意义。一旦涉密人员离职&#xff0c;可能会对单位的信息安全造成威胁&#xff0c;因此必须采取有效的措施来确保涉密人员离职后的信息安全。 一、涉密人员离职安全管理的现状 目前&#xff0c;许多单位在涉密人…