基础排序算法详解与对比分析

排序算法是计算机科学中最基础和重要的算法之一。本文将详细介绍几种经典的排序算法,包括选择排序、插入排序、希尔排序、堆排序和归并排序,并进行代码实现和对比分析。

选择排序(Selection Sort)

选择排序的基本思想是每次从未排序部分选择最小的元素,将其与未排序部分的第一个元素交换,从而逐步建立有序序列。其实现代码如下:

public class SelectionSort {// 选择排序方法public static void selectionSort(int[] array) {int n = array.length;for (int i = 0; i < n - 1; i++) {// 找到未排序部分的最小元素int minIndex = i;for (int j = i + 1; j < n; j++) {if (array[j] < array[minIndex]) {minIndex = j;}}// 将最小元素与未排序部分的第一个元素交换int temp = array[minIndex];array[minIndex] = array[i];array[i] = temp;}}
}
插入排序(Insertion Sort)

插入排序的基本思想是将数组划分为已排序和未排序两部分,逐个将未排序部分的元素插入到已排序部分的适当位置。其实现代码如下:

public class InsertionSort {// 插入排序方法public static void insertionSort(int[] array) {for (int i = 1; i < array.length; i++) {int key = array[i];int j = i - 1;// 将当前元素插入到已排序部分的正确位置while (j >= 0 && array[j] > key) {array[j + 1] = array[j];j--;}array[j + 1] = key;}}
}
希尔排序(Shell Sort)

希尔排序是插入排序的改进版,通过将数组分成多个子数组分别进行插入排序,然后逐步减少子数组的规模,最终进行一次标准的插入排序。其实现代码如下,使用给定的增量序列 (h = 7, 3, 1):

public class ShellSort {// 希尔排序方法public static void shellSort(int[] array) {int n = array.length;// 使用给定的增量序列 h = 7, 3, 1int[] gaps = {7, 3, 1};for (int gap : gaps) {// 对每个增量序列进行排序for (int i = gap; i < n; i++) {int temp = array[i];int j = i;// 将 temp 插入到合适的位置while (j >= gap && array[j - gap] > temp) {array[j] = array[j - gap];j -= gap;}array[j] = temp;}}}
}
堆排序(Heap Sort)

堆排序的基本思想是将数组构建成一个堆,然后重复地将堆顶元素(最大元素)与未排序部分的最后一个元素交换,并将剩余部分重新调整为堆,直到整个数组有序。其实现代码如下:

public class HeapSort {// 堆排序方法public static void heapSort(int[] array) {int n = array.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(array, n, i);}// 一个个将堆顶元素与末尾元素交换,并重新调整堆for (int i = n - 1; i > 0; i--) {// 交换堆顶元素和末尾元素int temp = array[0];array[0] = array[i];array[i] = temp;// 重新调整堆heapify(array, i, 0);}}// 将以i为根的子树调整为最大堆private static void heapify(int[] array, int n, int i) {int largest = i; // 根节点int left = 2 * i + 1; // 左子节点int right = 2 * i + 2; // 右子节点// 如果左子节点比根节点大if (left < n && array[left] > array[largest]) {largest = left;}// 如果右子节点比目前最大的节点大if (right < n && array[right] > array[largest]) {largest = right;}// 如果最大的节点不是根节点if (largest != i) {int swap = array[i];array[i] = array[largest];array[largest] = swap;// 递归地调整受影响的子树heapify(array, n, largest);}}
}
归并排序(Merge Sort)

归并排序的基本思想是将数组分成两部分,分别进行排序,然后合并两个有序的子数组。其实现代码如下:

public class MergeSort {// 归并排序方法public static void mergeSort(int[] array) {if (array.length > 1) {int mid = array.length / 2;// 分成两个子数组int[] left = new int[mid];int[] right = new int[array.length - mid];System.arraycopy(array, 0, left, 0, mid);System.arraycopy(array, mid, right, 0, array.length - mid);// 递归排序两个子数组mergeSort(left);mergeSort(right);// 合并两个有序子数组merge(array, left, right);}}// 合并两个有序子数组private static void merge(int[] array, int[] left, int[] right) {int i = 0, j = 0, k = 0;while (i < left.length && j < right.length) {if (left[i] <= right[j]) {array[k++] = left[i++];} else {array[k++] = right[j++];}}while (i < left.length) {array[k++] = left[i++];}while (j < right.length) {array[k++] = right[j++];}}
}

算法对比分析

对这些排序算法的运行时间和空间复杂度进行对比分析如下:

排序算法最好情况时间复杂度最坏情况时间复杂度空间复杂度备注
选择排序Θ(N²)Θ(N²)Θ(1)简单但效率低,适用于小规模数据集
堆排序(不使用多余空间)Θ(N)Θ(N log N)Θ(1)相对较快,但在缓存性能方面表现较差
归并排序Θ(N log N)Θ(N log N)Θ(N)在大多数情况下最快,但需要额外的内存空间
插入排序(不使用多余空间)Θ(N)Θ(N²)Θ(1)最适合小规模或近乎有序的数据集
希尔排序Θ(N)Ω(N log N) O(?)Θ(1)理论丰富,性能视增量序列而定

结论

  1. 选择排序:简单直观,但在处理大规模数据时效率低下,适合小规模数据集。
  2. 插入排序:在数据几乎有序或规模较小时非常高效。
  3. 希尔排序:通过增量序列优化插入排序,性能依赖于具体的增量序列选择。
  4. 堆排序:时间复杂度较低,特别是在最坏情况下,但在处理大规模数据时,缓存性能表现不佳。
  5. 归并排序:在大多数情况下效率最高,但需要额外的内存空间。

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

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

相关文章

Ubuntu修改MySQL的tmpdir参数失败的解决方法

问题 在查询大表时&#xff0c;MySQL提示ERROR 3 (HY000): Error writing file /tmp/MYfd268 (OS errno 28 - No space&#xff0c;应该是临时文件夹/tmp没有足够的空间&#xff1b;想修改文件夹/etc/mysql/my.cnf中的参数tmpdir命令改变临时文件夹&#xff1b; sudo nano /e…

《青少年编程与数学》课程方案:3、课程形式

《青少年编程与数学》课程方案&#xff1a;3、课程形式 一、这门课程是一门学习课程&#xff0c;不是教学课程二、这门课程是一门独立的课程&#xff0c;不是多门课程三、这门课程有一条主要的线索是计算四、这门课程需要重视输出、强调可见性五、这门课程需要灵活运用&#xf…

C/C++函数指针、C#委托是什么?

函数指针 #include<stdio.h>//声明函数指针 typedef int(*Calc)(int a, int b); int Add(int a, int b) {return a b; } int Sub(int a, int b) {return a - b; }int main() {Calc funcPoint1 &Add;Calc funcPoint2 &Sub;int x 120;int y 140;int z 0;z …

Docker 部署 RocketMQ

0. 拉取镜像 docker pull apache/rocketmq:5.2.0 docker pull styletang/rocketmq-console-ng1. 创建容器共享网络 docker network create rocketmq2. 启动NameServer # 启动 NameServer docker run -d --name rmqnamesrv -p 9876:9876 --network rocketmq apache/rocketmq:…

【YashanDB知识库】PHP使用OCI接口使用数据库绑定参数功能异常

【问题分类】驱动使用 【关键字】OCI、驱动使用、PHP 【问题描述】 PHP使用OCI8连接yashan数据库&#xff0c;使用绑定参数获取数据时&#xff0c;出现报错 如果使用PDO_OCI接口连接数据库&#xff0c;未弹出异常&#xff0c;但是无法正确获取数据 【问题原因分析】 开启O…

实例方法与静态方法

实例方法&#xff08;非静态方法&#xff09; 定义&#xff1a;实例方法是与类的实例&#xff08;对象&#xff09;相关联的方法。它们可以访问类的实例变量&#xff08;非静态变量&#xff09;&#xff0c;也可以访问类的静态变量和方法。 访问&#xff1a;实例方法必须通过类…

wangEditor富文本编辑器的调用开发实录(v5版本、多个编辑器、php后端上传视频阿里云OSS、编辑HTML回显)

wangEditor富文本编辑器的调用开发实录(v5版本、获取HTML内容、上传图片、隐藏上传视频)wangEditor富文本编辑器的调用开发实录2(V5版本自定义粘贴&#xff0c;去除复制word或网页html冗余样式代码的解决方案) wangEditor富文本编辑器的调用开发实录 一、多个编辑器1.构建HTML容…

张艺兴step新专开启自由驾驶新纪元

张艺兴《Step》新专&#xff0c;开启自由驾驶新纪元&#xff01;当音乐与驾驶相遇&#xff0c;会碰撞出怎样的火花&#xff1f;当实力派艺人张艺兴遇上全新英文专辑《Step》&#xff0c;便为我们解锁了一种前所未有的出行体验&#xff01;这不仅仅是一张音乐专辑&#xff0c;更…

Pandas AI:最棒的大模型数据分析神器!

暑期实习基本结束了&#xff0c;校招即将开启。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解惑答疑&…

MySQL中为什么要有隐式内连接和显式内连接

在MySQL多表联合查询中&#xff0c;区分隐式内连接&#xff08;Implicit Inner Join&#xff09;和显式内连接&#xff08;Explicit Inner Join&#xff09;的主要原因在于它们的语法风格、可读性、可维护性以及应用场景的差异。以下是对这两种连接方式的主要区别的详细分析&am…

Java Opencv识别图片上的虫子

最近有个需求&#xff0c;希望识别图片上的虫子&#xff0c;对于java来说&#xff0c;图像识别不是很好做。在网上也搜索了很多&#xff0c;很多的代码都是不完整&#xff0c;或者下载下载报错&#xff0c;有的写的很长看不懂。所以自己试着用java的opencv写了一段代码。发现识…

2024年计算机相关专业是否适合选择

2024年&#xff0c;计算机相关专业还值得选择吗&#xff1f; 随着2024年高考落幕&#xff0c;数百万高三学生又将面临人生中的重要抉择&#xff1a;选择大学专业。在这个关键节点&#xff0c;计算机相关专业是否仍是“万金油”的选择&#xff1f;在过去很长一段时间里&#xf…

Django+Vue.js怎么实现搜索功能

一.前言 类似这样的搜索功能 二.前端代码 <div class"form-container"><div class"form-group"><label for"departure-city">出发城市</label><select v-model"departureCity" id"departure-city&q…

把Vue项目从Window系统迁移到Mac系统的方案

不能启动vue ui 直接运行&#xff0c;会报错如下&#xff1a; failed to load config from /Users/xiaochen/IdeaProjects/ChatViewer-frontend/vite.config.tserror when starting dev server: Error: You installed esbuild for another platform than the one youre curre…

C++:STL容器-->set

使用set容器时需要导入头文件&#xff1a;#include <set> set和multiset区别&#xff1a; set不允许容器中有重复的元素 multiset允许容器中有重复的元素 1. 构造函数 set<T> st; set s(const &st); void printSet(set<int>& s) {for (set<int>…

程序性能优化——接口性能优化总结和思考

程序性能优化——接口性能优化总结和思考 一、背景介绍二、 思路方案三、过程四、总结五、升华 一、背景介绍 接口的优化 排查到的问题&#xff1a;循环中查询数据库&#xff0c;4300次查询数据库总共耗时在4分钟左右。 优化结果&#xff1a;4分钟到2秒 二、 思路方案 宏观的…

QT高阶-QSS样式表用法大全

文章目录 使用全局样式设置字体样式的作用域修改全局控件指示器的样式动态刷新控件的样式QSS样式的优先级调节控件的边框线QT6样式用法差异添加控件的背景图QSS注意事项Qt Style Sheet(QSS)是Qt的一种强大功能,类似于CSS用于网页设计。通过QSS,你可以定义Qt应用程序中的控件的…

RichSinkFunction 在 Flink IoT 项目中的应用实战

一、引言 随着物联网&#xff08;IoT&#xff09;技术的快速发展&#xff0c;实时数据处理和分析的需求日益增长。Apache Flink 作为一款高性能的流处理框架&#xff0c;广泛应用于 IoT 项目中。在 Flink 中&#xff0c;RichSinkFunction 是一种特殊的函数&#xff0c;它允许用…

嵌入式操作系统_5.存储管理

1.存储管理 存储管理是嵌入式操作系统的基本功能之一。其管理的对象是主存&#xff0c;也称内存。它的主要功能包括分配和回收主存空间、提高主存利用率、扩充主存、对主存信息实现有效保护。存储器管理的目的就是提供一个有价值的内存抽象&#xff0c;其目标包括&#xff1a;…

Integer溢出问题

0. 背景 在刷 LeetCode 时&#xff0c;代码的执行结果与预期出现了偏差&#xff0c;原因是 Int 值超过了允许范围 [ − 2 31 , 2 31 − 1 ] [-2^{31},2^{31}-1 ] [−231,231−1]。工作中从来没有遇到过这种情况&#xff0c;之前的认知是如果 Int 中存储的值超过了允许范围也许…