什么是排序
排序即是,输入包含\(n\)个数的数列\((a_1,a_2,a_3,\cdots,a_n)\),通过某个过程生成数列\((a'_1,a'_2,a'_3,\cdots,a'_n)\)。
其中:\(a'_1<=a'_2<=...<=a'_n\).
更一般的,可以表述为,使一个乱序的数列最终根据某种规则排列的过程,即是排序
插入排序
插入排序是一种排序方法。他的核心思想是,逐个的读取数列中的值,向该值前面的有序子数列插入。当数列读完的时候,整个数列也就排序完毕了
如上图所示,我们对数列\((5,2,4,6,1,3)\)排序。比如我们已经读取到\(4\)这个数值,就将\(4\)插入\((2,5)\)这个子有序数列中。最后,形成子数列\((2,4,5)\)。后面的步骤以此类推,直到最后一个数值\(3\)。
最终,形成数列\((1,2,3,4,5,6)\)。
代码实现(Java)
/**
* @author: luzj
* @date:
* @description: 插入排序,增长率为O(n^2)
* 0 从第二位开始进行比较排序,朝前面有序数列插入新值
* 1 因此,每插入一个新值,就要遍历前面的有序数列,时间为O(n*n)
* 2 在比较小的输入下,实际上使用插入反倒比快排、归并等经济
*/
public class InsertSort {
void insertionSort(Integer[] A) {
for (int j = 1; j < A.length; j++) {
Integer key = A[j];
//想象一下,将A[j]插到有序数列A[0...j-1]中去
//如果A[j]大于A[j-1],那么A[j]就直接坐落于A[j]的位置,不要重排
//若A[j]位于A[0...j-1]中,那么就逐个和A[j-1...0]比较,寻找合适的位置
int i = j - 1;
while (i >= 0 && A[i] > key) {
A[i + 1] = A[i];
i--;
}
A[i + 1] = key;
}
}
//测试
public static void main(String[] args) {
Integer[] A= {5,2,4,6,1,3};
new InsertSort().insertionSort(A);
for (int i = 0; i < A.length; i++) {
System.out.print(A[i]+" ");
}
}
}
时间复杂度
在最坏的情况下,插入排序的时间复杂性为:\(O(n^2)\)
最好的情况为:\(O(n)\),即当原始数列为有序数列的时候。由于我们不太可能针对有序数列排序,因此意义不大。
当排序数列比较小的时候,事实上,插入排序的性能反倒比快排等分治法策略的算法,还要好一些。而且还有简单易懂的特点