声明
本文是博主在Coursera学习时所写的学习笔记,如有错误疏漏还望各位指正。
欢迎交流讨论
如果大家转载,请注明本文地址!
简介
- 排序是指通过一定的方法将一组无序的数组按照一定的规则顺序排列,排序是计算机中常用的操作之一。今天介绍一些基本排序算法。
选择排序
工作原理
是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完
例如i min 0 1 2 3 4 5 4 3 8 9 2 1 0 5 1 3 8 9 2 4 1 4 1 2 8 9 3 4 2 4 1 2 3 9 8 4 3 5 1 2 3 4 8 9 4 1 2 3 4 8 9 5 1 2 3 4 8 9 说明:
- 粗体部分为未排序部分
- i是指第i次遍历数组
- min是指未排序部分中最小的数字的下标
时间复杂度
- 比较次数: (N–1)+(N–2)+...+1+0 ~ 12N2
- 交换次数: N
代码实现
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);}}private static boolean less(Comparable v, Comparable w){ //在java中,compareTo(w)函数可以通过实现Comparable接口来复写,从而按照需要的规则排序return v.compareTo(w) < 0;}//交换数组中下标为i,j的元素private static void exch(Comparable[] a, int i, int j){ Comparable swap = a[i];a[i] = a[j];a[j] = swap;}
}
注
选择算法是不稳定的排序算法,比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面
插入排序
工作原理
- 将列表分为两部份,有虚标和无序表,初始时无序表为所有元素,有序表为空。每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
红色的为a[j]
灰色的是为排序的
黑色的是已经能够完成排序的时间复杂度
- 比较次数:
14N2 - 交换次数: 14N2
- 比较次数:
代码实现
public class Insertion {
public static void sort(Comparable[] a){int N = a.length;for (int i = 0; i < N; i++)for (int j = i; j > 0; j--)if (less(a[j], a[j-1]))exch(a, j, j-1);else break;}private static boolean less(Comparable v, Comparable w){ //在java中,compareTo(w)函数可以通过实现Comparable接口来复写,从而按照需要的规则排序return v.compareTo(w) < 0;}//交换数组中下标为i,j的元素private static void exch(Comparable[] a, int i, int j){ Comparable swap = a[i];a[i] = a[j];a[j] = swap;}
}
注
选择算法是稳定的排序算法。
希尔排序
工作原理
时间复杂度
希尔排序的时间复杂度取决其增量h的选择,自从1959shell提出这个算法以来人们一直在探索最佳的增量,但是因为无法建立一个准确的模型而精确的找到答案。Knuth在他的书中使用的是 3X+1 ,在这门课中Robert Sedgewick教授提供了一组增量 1,5,9,41,109,209,505,929 。
代码实现
public class Shell {
public static void sort(Comparable[] a){int N = a.length;int h = 1;while (h < N/3) h = 3*h + 1; // 1, 4, 13, 40, 121, 364, ...while (h >= 1){ // h-sort the array.for (int i = h; i < N; i++){for (int j = i; j >= h && less(a[j], a[j-h]); j -= h)exch(a, j, j-h);}h = h/3;}}private static boolean less(Comparable v, Comparable w){ //在java中,compareTo(w)函数可以通过实现Comparable接口来复写,从而按照需要的规则排序return v.compareTo(w) < 0;}//交换数组中下标为i,j的元素private static void exch(Comparable[] a, int i, int j){ Comparable swap = a[i];a[i] = a[j];a[j] = swap;}
}