【数据结构】——八大排序(以Java为例)

https://www.cnblogs.com/yzsn12138/p/16989094.html

 

主要内容如下

作为高级语言(以下的代码都以Java)为例,如果需要对数组排序,通常都是直接调用排序方法 sort 。例如:

 1  int [] sortArray = {1,4,7,5,8,10,2,3,9,6};
 2 // 排序前
 3 System.out.println("排序前数组");
 4 for (int i: sortArray) {
 5     System.out.print(i + ",");
 6 }
 7 System.out.println();
 8 Arrays.sort(sortArray);
 9 System.out.println("排序后数组:");
10 for (int i: sortArray) {
11     System.out.print(i + ",");
12 }
13 System.out.println();
Arrays.sort排序

 所以,似乎实际不需要知道排序的原理也不影响工作。

不过,它是数据结构的基础。知其然,并且知其所以然,才能不蒙昧。所以,今天,我们来复习常见的八大排序方法,并对比这几种排序的属性。八大排序方法的分类如下:

 

基本概念概述

排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。

时间复杂度:又称时间复杂性,用于评估执行程序所消耗的时间,可以估算出程序对处理器的使用程度。

空间复杂度:有称空间复杂性,用于评估执行程序所占用的内存空间,可以估算出程序对处理器的使用程度。

排序的稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,在排序后的序列中,r[i]仍然在r[j]之前,则称这种排序算法是稳定的,否则称为不稳定。为了方面理解,示意图如下。

 开门直接抛出主题,各种排序的综合比较如下:

排序方法  平均情况 最好情况  最坏情况   辅助空间 稳定性 
 直接插入排序  O(n^2)  O(n)  O(n^2)  O(1)  稳定
 希尔排序  O(nlogn~n^2) O(n^1.3)  O(n^2)  O(1)   不稳定
 直接选择排序  O(n^2) O(n^2)  O(n^2)  O(1)   不稳定
 堆排序  O(nlogn) O(nlogn)  O(nlogn)  O(1)  不稳定
 冒泡排序  O(n^2) O(n)  O(n^2)  O(1)   稳定
 快速排序  O(nlogn) O(nlogn)   O(n^2) O(1)   不稳定
 归并排序  O(nlogn)  O(nlogn)  O(nlogn)  O(n)  稳定
 计数排序  O(N)  O(N)    O(N)  O(N)  不稳定

 


直接插入排序

基本思想

把待排序的数逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列。

✍️一般地,我们把第一个看作是有序的,所以我们可以从第二个数开始往前插入,使得前两个数是有序的,然后将第三个数插入直到最后一个数插入。

思路图示

口头描述有些太抽象了。我们不妨用图表示排序的方法(这里以数组:1,4,7,5,8,10,2,3,9,6)为例。

 

 

注:从小到大排列,则从数列的右边到左边依次替换;如果从大到小排列,则从数列的左边到右边依次替换。

实现代码

 1 public  void  insertSort(int[] arrs ){
 2         int n = arrs.length;
 3         int temp ;              // 定义一个变量,将要插入的数保存起来
 4         for(int i = 0 ; i < n -1 ; i ++){
 5             temp = arrs[i + 1];
 6             for (int j = i ; j >= 0 ; j --){
 7                 if(temp >= arrs[j]){
 8                     break;
 9                 }else{
10                     arrs[j+ 1] = arrs [j];
11                     arrs[j] = temp;
12                 }
13             }
14         }
15     }

 

直接排序分析

  • 时间复杂度:第一趟end最多往前移动1次,第二趟是2次……第n-1趟是n-1次,所以总次数是1+2+3+……+n-1=n*(n-1)/2,所以说时间复杂度是O(n^2)

    最好的情况: 顺序
    最坏的情况: 逆序

外层的循环次数,复杂度是O(logN)

每一组的数的个数大概是N/gap,总共有N/n/gap个组,所以调整的次数应该是(1+2+......+N/gap-1)*gap,所以我们分成两种极端来看待这个问题:

当gap很大,也就是gap = N/2的时候,调整的次数是N/2,也就是O(N)

当gap很小,也就是gap = 1的时候,按道理来讲调整的次数应该(1+2+......+N-1)*gap,应该是O(n^2),但是这时候应该已经接近有序,次数没有那么多,所以我们不如就看作时间复杂度为O(N)

综上:希尔排序的时间复杂度应该是接近O(N*logN)

  • 空间复杂度由于没有额外开辟空间,所以空间复杂度为O(1)。
  • 稳定性:稳定。

希尔排序

基本思路

希尔排序是建立在直接插入排序之上的一种排序,希尔排序的思想上是把较大的数尽快的移动到后面,把较小的数尽快的移动到后面。先选定一个整数,把待排序文件中所有记录分成个组,所有距离为的记录分在同一组内,并对每一组内的记录进行排序。(直接插入排序的步长为1),这里的步长不为1,而是大于1,我们把步长这个量称为gap,当gap>1时,都是在进行预排序,当gap==1时,进行的是直接插入排序。

思路图示

实现代码

希尔排序分析

  

  • 时间复杂度:第一趟end最多往前移动1次,第二趟是2次……第n-1趟是n-1次,所以总次数是1+2+3+……+n-1=n*(n-1)/2,所以说时间复杂度是O(n^2)

最好的情况: 顺序。

最坏的情况: 逆序。

  • 空间复杂度由于没有额外开辟空间,所以空间复杂度为O(1)。
  • 稳定性:不稳定。 我们可以这样想:相同的数被分配到不同的组里,我们就不能保证原有的顺序了。

直接选择排序

堆排序

冒泡排序

快速排序

归并排序

 

posted @ 2023-09-09 17:18  陆陆无为而治者  阅读(65)  评论(0编辑  收藏  举报