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

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

插入排序

插入排序过程

基本思想:

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

直接插入排序

当插入第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.


相关文章
|
3月前
|
存储 算法 搜索推荐
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
专攻软考高频算法,深度解析二分查找、堆排序、快速排序核心技巧,对比九大排序算法,配套动画与真题,7天掌握45%分值模块。
176 1
软考算法破壁战:从二分查找到堆排序,九大排序核心速通指南
|
5月前
|
搜索推荐
选择排序与其它排序算法比较
选择排序与冒泡排序同属O(n²)排序算法,但选择排序不稳定。相比堆排序,虽每轮均选最大元素,但选择排序基于线性结构,效率较低,而堆排序利用大顶堆结构提升了选择效率。
98 0
|
搜索推荐 C语言
【排序算法】快速排序升级版--三路快排详解 + 实现(c语言)
本文介绍了快速排序的升级版——三路快排。传统快速排序在处理大量相同元素时效率较低,而三路快排通过将数组分为三部分(小于、等于、大于基准值)来优化这一问题。文章详细讲解了三路快排的实现步骤,并提供了完整的代码示例。
430 4
|
8月前
|
算法 搜索推荐
快速排序-数据结构与算法
快速排序(Quick Sort)是一种基于分治法的高效排序算法。其核心思想是通过选择基准(pivot),将数组划分为左右两部分,使得左侧元素均小于基准,右侧元素均大于基准,然后递归地对左右两部分进行排序。时间复杂度平均为 O(n log n),最坏情况下为 O(n²)(如数组已有序)。空间复杂度为 O(1),属于原地排序,但稳定性不佳。 实现步骤包括编写 `partition` 核心逻辑、递归调用的 `quickSort` 和辅助函数 `swap`。优化方法有随机化基准和三数取中法,以减少最坏情况的发生。
559 13
|
10月前
|
存储 搜索推荐 算法
算法系列之排序算法-堆排序
堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。它的时间复杂度为 $O(nlogn)$,并且是一种原地排序算法(即不需要额外的存储空间)。堆排序的核心思想是利用堆的性质来维护一个最大堆或最小堆,然后逐步将堆顶元素(最大值或最小值)取出,放到数组的末尾,最终得到一个有序的数组。
261 8
算法系列之排序算法-堆排序
|
存储 搜索推荐 Python
用 Python 实现快速排序算法。
快速排序的平均时间复杂度为$O(nlogn)$,空间复杂度为$O(logn)$。它在大多数情况下表现良好,但在某些特殊情况下可能会退化为最坏情况,时间复杂度为$O(n^2)$。你可以根据实际需求对代码进行调整和修改,或者尝试使用其他优化策略来提高快速排序的性能
292 61
|
2月前
|
机器学习/深度学习 算法 机器人
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
【水下图像增强融合算法】基于融合的水下图像与视频增强研究(Matlab代码实现)
223 0
|
2月前
|
数据采集 分布式计算 并行计算
mRMR算法实现特征选择-MATLAB
mRMR算法实现特征选择-MATLAB
170 2
|
3月前
|
传感器 机器学习/深度学习 编解码
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
MATLAB|主动噪声和振动控制算法——对较大的次级路径变化具有鲁棒性
210 3
|
2月前
|
机器学习/深度学习 算法 机器人
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
使用哈里斯角Harris和SIFT算法来实现局部特征匹配(Matlab代码实现)
155 8

热门文章

最新文章