《算法(第四版)》排序-----插入排序

来源:互联网 发布:洛天依黑暗五部曲 知乎 编辑:程序博客网 时间:2024/06/06 03:28

插入排序:

插入排序与选择排序一样,当前索引左边的所有元素都是有序的,但和选择排序不一样的是它们的位置不是固定的,可能为了更小的元素腾出空间,它们向后移动,但是当索引达到数组的右端时,数组排序就完成了
使用插入排序为一列数字进行排序的过程

具体算法描述如下:

  1. 从第一个元素开始,该元素可以认为已经被排序
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
  5. 将新元素插入到该位置后
  6. 重复步骤2~5

与选择排序的不同,插入排序所需的时间取决于输入元素的初始顺序,对一个很大且其中元素已经有序(或接近有序)的数组进行排序比随机顺序的数组或逆序的数组排序要快的多。


最坏的请款进行n^2/2次比较和N^2/2次交换,最好情况进行N-1次比较,0次交换

平均  n^2/4次比较和N^2/4次交换,所以插入排序的比较次数平均只有选择排序比较次数的一半

具体实现如下:

public static <T> void insertSort(Comparable<T>[] a){// 将a[] 升序排列    int N = a.length;    for (int i = 1; i < N; i++) {//默认a[0]已经是有序的了,所以从a[1]开始检查        //检查新的元素是否比前面的元素小,只要小就交换,直到不小位置,由于前面的已经是有序的了,有一个不小,那前面的都不小        for(int j = i; j > 0 && less(a[j],a[j-1]);j--)            exch(a,j,j-1);//只要碰到小的就交换    }}
测试程序如下

public class InsertionSort {public static <T> void insertSort(Comparable<T>[] a){// 将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);}}}private static <T>boolean less(Comparable<T> v, Comparable<T> w){return v.compareTo((T) w) < 0;}private static <T> void exch(Comparable<T>[] a, int i, int j){Comparable<T> t = a[i];a[i] = a[j];a[j] = t;}private static <T> void show(Comparable<T>[] a){//在单行中打印数组for (int i = 0; i < a.length; i++) {System.out.print(a[i] + " ");}}public static <T> boolean isSorted(Comparable<T>[] a){//测试数组元素是否有序for (int i = 0; i < a.length; i++) {if(less(a[i], a[i-1]))return false;}return true;}public static void main(String[] args) throws FileNotFoundException {// TODO Auto-generated method stub//String[] a = {"S","O","R","T","E","X","A","M","P","L","E"};Integer[] a = {-5,8,9,5,7,1,-68,1,5,33,100,563,526,16,21,68,-88};for (int i = 0; i < a.length; i++) {System.out.print(a[i] + " ");}System.out.println();insertSort(a);assert isSorted(a);show(a);}}


和选择排序不同的是,插入排序所需要的时间取决有输入中元素的出示顺序,例如,对一个很大且其中的元素已经有序(或接近有序)的数组进行排序将会比对随机顺序的数组或逆序数组进行排序要快的多。







0 0
原创粉丝点击