七大排序算法—图文详解(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)(一)

简介: 七大排序算法—图文详解(插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序)

插入排序

插入排序过程

基本思想:

把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列 。实际中我们玩扑克牌时,就用了插入排序的思想。

直接插入排序

当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移

插入排序

代码实现:

1. //插入排序:
2. public void insertSort(int[]arr){
3. 
4. for (int i = 1; i < arr.length ; i++) {
5. int j=i-1;
6. int tmp=arr[i];
7. while(j>=0){
8. 
9. if(arr[j]>tmp){
10.                     arr[j+1]=arr[j];
11.                 }
12. if(arr[j]<tmp){
13.                     arr[j+1]=tmp;
14. break;
15.                 }
16.                 j--;
17.             }
18.             arr[j+1]=tmp;
19.         }
20.     }

直接插入排序的特性总结:

1. 元素集合越接近有序,直接插入排序算法的时间效率越高

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1),它是一种稳定的排序算法

4. 稳定性:稳定

希尔排序:

基本思想:

希尔排序法又称缩小增量法。希尔排序法的基本思想是:先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。然后,取,重复上述分组和排序的工作。当到达=1时,所有记录在统一组内排好序。

 

代码实现:

1. public void shellSort(int[]arr){
2. 
3. int gap= arr.length/2;
4. 
5. while(gap>=1){
6. 
7. for(int i=gap;i<arr.length;i++){
8. int j=i-gap;
9. int tmp=arr[i];
10. while(j>=0){
11. 
12. if(arr[j]>tmp){
13.                         arr[j+gap]=arr[j];
14.                     }
15. if(arr[j]<tmp){
16.                         arr[j+gap]=tmp;
17. break;
18.                     }
19.                     j-=gap;
20.                 }
21.                 arr[j+gap]=tmp;
22. 
23.             }
24.             gap/=2;
25.         }
26.     }

希尔排序的特性总结:

1. 希尔排序是对直接插入排序的优化。

2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。

3. 希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些树中给出的希尔排序的时间复杂度都不固定:

4. 稳定性:不稳定

选择排序:

选择排序过程

基本思想:

每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完

直接选择排序:

在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素

若它不是这组元素中的最后一个(第一个)元素,则将它与这组元素中的最后一个(第一个)元素交换在剩余的array[i]--array[n-2](array[i+1]--array[n-1])集合中,重复上述步骤,直到集合剩余1个元素

选择排序

代码实现:

1. public void selectSort(int[]arr){
2. 
3. for(int i=0;i< arr.length;i++){
4. int minIndex=i;
5. 
6. int j=i+1;
7. while(j< arr.length){
8. 
9. if(arr[j]<arr[minIndex]){
10.                     minIndex=j;
11.                 }
12. 
13.                 j++;
14.             }
15. if(minIndex!=i){
16.                 swap(arr,i,minIndex);
17.             }
18. 
19.         }
20. 
21.     }
22. public void swap(int[]arr,int i,int j){
23. int temp=arr[i];
24.         arr[i]=arr[j];
25.         arr[j]=temp;
26.     }

【直接选择排序的特性总结】

1. 直接选择排序思考非常好理解,但是效率不是很好。实际中很少使用

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:不稳定

堆排序

堆排序过程

堆排序在博主的这一篇文章有详细解释:

网络异常,图片无法展示
|

交换排序

基本思想:

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

冒泡排序:

冒泡排序在博主的这一篇文章有详细解释:

网络异常,图片无法展示
|

【冒泡排序的特性总结】

1. 冒泡排序是一种非常容易理解的排序

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:稳定

快速排序:

快速排序过程

基本思想:

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止

快速排序

Hoare递归代码实现:

1. /**
2.      * 快速排序(Hoare版)
3.      * 时间复杂度:O(n*logn)
4.      * 空间复杂度:O(logn)
5.      * 稳定性:不稳定
6.      * @param arr
7.      * 问题:当我们给定的数据是有序的时候其时间复杂度为O(n^2),空间复杂度达到了O(n)
8.      */
9. public void quickSort(int[]arr){
10.         quick(arr,0,arr.length-1);
11.     }
12. 
13. private void quick(int[]arr,int start,int end){
14. 
15. if(start>=end){
16. return;
17.         }
18. 
19. int pivot=pivotPartationHoare(arr,start,end);
20.         quick(arr,start,pivot-1);
21.         quick(arr,pivot+1,end);
22.     }
23. //Hoare法
24. private int pivotPartationHoare(int[]arr,int left,int right){
25. int i=left;
26. int pivot=arr[left];
27. 
28. while(left<right){
29. 
30. //left<right不能少,否则会出现越界
31. while (left<right&&arr[right]>=pivot){
32.                 right--;
33.             }
34. while (left<right&&arr[left]<=pivot){
35.                 left++;
36.             }
37. 
38. //都找到后交换
39.             swap(arr,left,right);
40. 
41.         }
42. 
43. //一边找完之后和原来的left交换
44.         swap(arr,left,i);
45. 
46. return left;//为新的基准
47. 
48.     }
49. 
50. public void swap(int[]arr,int i,int j){
51. int temp=arr[i];
52.         arr[i]=arr[j];
53.         arr[j]=temp;
54.     }
55.


目录
打赏
0
0
0
0
2
分享
相关文章
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
90 4
利用Python内置函数实现的冒泡排序算法
在上述代码中,`bubble_sort` 函数接受一个列表 `arr` 作为输入。通过两层循环,外层循环控制排序的轮数,内层循环用于比较相邻的元素并进行交换。如果前一个元素大于后一个元素,就将它们交换位置。
161 67
用 Python 实现快速排序算法。
快速排序的平均时间复杂度为$O(nlogn)$,空间复杂度为$O(logn)$。它在大多数情况下表现良好,但在某些特殊情况下可能会退化为最坏情况,时间复杂度为$O(n^2)$。你可以根据实际需求对代码进行调整和修改,或者尝试使用其他优化策略来提高快速排序的性能
156 61
冒泡排序算法
【10月更文挑战第19天】冒泡排序是一种基础的排序算法,虽然在实际应用中可能不是最优的选择,但对于理解排序算法的基本原理和过程具有重要意义。
排序算法--冒泡排序
排序算法--冒泡排序
34 0
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
本研究基于MATLAB 2022a,使用GRU网络对QAM调制信号进行检测。QAM是一种高效调制技术,广泛应用于现代通信系统。传统方法在复杂环境下性能下降,而GRU通过门控机制有效提取时间序列特征,实现16QAM、32QAM、64QAM、128QAM的准确检测。仿真结果显示,GRU在低SNR下表现优异,且训练速度快,参数少。核心程序包括模型预测、误检率和漏检率计算,并绘制准确率图。
83 65
基于GRU网络的MQAM调制信号检测算法matlab仿真,对比LSTM
基于PSO粒子群优化的CNN-LSTM-SAM网络时间序列回归预测算法matlab仿真
本项目展示了基于PSO优化的CNN-LSTM-SAM网络时间序列预测算法。使用Matlab2022a开发,完整代码含中文注释及操作视频。算法结合卷积层提取局部特征、LSTM处理长期依赖、自注意力机制捕捉全局特征,通过粒子群优化提升预测精度。适用于金融市场、气象预报等领域,提供高效准确的预测结果。
基于Big-Bang-Big-Crunch(BBBC)算法的目标函数最小值计算matlab仿真
该程序基于Big-Bang-Big-Crunch (BBBC)算法,在MATLAB2022A中实现目标函数最小值的计算与仿真。通过模拟宇宙大爆炸和大收缩过程,算法在解空间中搜索最优解。程序初始化随机解集,经过扩张和收缩阶段逐步逼近全局最优解,并记录每次迭代的最佳适应度。最终输出最佳解及其对应的目标函数最小值,并绘制收敛曲线展示优化过程。 核心代码实现了主循环、粒子位置更新、适应度评估及最优解更新等功能。程序运行后无水印,提供清晰的结果展示。
基于CS模型和CV模型的多目标协同滤波跟踪算法matlab仿真
本项目基于CS模型和CV模型的多目标协同滤波跟踪算法,旨在提高复杂场景下多个移动目标的跟踪精度和鲁棒性。通过融合目标间的关系和数据关联性,优化跟踪结果。程序在MATLAB2022A上运行,展示了真实轨迹与滤波轨迹的对比、位置及速度误差均值和均方误差等关键指标。核心代码包括对目标轨迹、速度及误差的详细绘图分析,验证了算法的有效性。该算法结合CS模型的初步聚类和CV模型的投票机制,增强了目标状态估计的准确性,尤其适用于遮挡、重叠和快速运动等复杂场景。
基于Adaboost的数据分类算法matlab仿真
本程序基于Adaboost算法进行数据分类的Matlab仿真,对比线性与非线性分类效果。使用MATLAB2022A版本运行,展示完整无水印结果。AdaBoost通过迭代训练弱分类器并赋予错分样本更高权重,最终组合成强分类器,显著提升预测准确率。随着弱分类器数量增加,训练误差逐渐减小。核心代码实现详细,适合研究和教学使用。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等