初级排序算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38283262/article/details/83544409

前言

排序算法的成本模型计算的是比较和交换的次数。less()方法对元素进行比较,exch()方法将元素交换位置。

private static boolean less(Comparable v, Comparable w) {
   return (v.compareTo(w) < 0);
}

private static void exch(Comparable[] a, int i, int j) {
   Comparable swap = a[i];
   a[i] = a[j];
   a[j] = swap;
} 

选择排序

首先找到数组中最小的那个元素,其次将它和数组的第一个元素交换位置。再次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此反复,直到将整个数组排序。

选择排序
@选择排序的示例动画。红色表示当前最小值,黄色表示已排序序列,蓝色表示当前位置。

特点

  • 运行时间和输入无关:一个已经有序的数组或主键全部相等的数组和一个元素随机排列的数组所用的排序时间一样长。
  • 数据移动是最少的:每次交换都会改变两个数组的元素的值,因此选择排序用了N次交换。

复杂度分析

比较次数与关键字的初始状态无关,总的比较次数N = (n - 1) + (n - 2) +...+ 1 = n × (n - 1 ) / 2。交换次数最好情况是已经有序,交换0次;最坏情况是逆序,交换n-1次。

  • 最坏时间复杂度 О(n²)
  • 最优时间复杂度 О(n²)
  • 平均时间复杂度 О(n²)
  • 空间复杂度 O(1)
  • 不稳定

实现

public class Selection {
    public static void sort(Comparable[] a) {
        int n = a.length;
        for (int i = 0; i < n; i++) {
            int min = i;
            for (int j = i+1; j < n; j++) {
                if (less(a[j], a[min])) min = j;
            }
            exch(a, i, min);
        }
    }
}

插入排序

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

插入排序

特点

  • 插入排序所需时间取决于输入中元素的初始顺序。
  • 插入排序对于部分有序的数组十分高效。

复杂度分析

最好情况是序列已经是升序排列了,在这种情况下,需要进行的比较操作需n-1次即可,不需要进行交换;最坏情况是降序排列,那么此时需要进行的比较共有n × (n - 1) / 2次,交换同样需要n × (n - 1) / 2次。

  • 最坏时间复杂度 О(n²)
  • 最优时间复杂度 О(n)
  • 平均时间复杂度 О(n²)
  • 空间复杂度 O(1)
  • 稳定

实现

public class Insertion {
    public static void sort(Comparable[] a) {
        int n = a.length;
        for (int i = 1; i < n; i++) {
            for (int j = i; j > 0 && less(a[j], a[j-1]); j--) {
                exch(a, j, j-1);
            }
        }
    }
}

待更…

参考资料

猜你喜欢

转载自blog.csdn.net/qq_38283262/article/details/83544409