校园时光不多,准备找工作,多看点东西增加知识,为自己助力!加油!
插入排序:简单的排序方法
基本的操作:将一个新的记录插入到已经排好序的有序数组中
影响时间复杂度的因素:记录间的比较与移动
原始的插入排序算法:时间复杂度O(n2)
1 //插入排序算法 2 public void simpleSort(int[] array){ 3 for(int i=1; i<array.length; i++){ 4 int temp = array[i]; 5 if(array[i]<array[i-1]){ 6 array[i]=array[i-1]; 7 int j=i-2; 8 for(; j>=0&&temp<array[j]; j--){ 9 array[j+1]=array[j]; 10 } 11 array[j+1]=temp; 12 } 13 14 } 15 }
折半插入排序:使用折半查找,找出已经排序好的数组中,新的记录应该插入的位置。
改进效果:记录之前的比较次数减少了,但移动次数不变,因此时间复杂度不变。
/* * 折半插入排序 * 目的:减少比较次数 * 时间复杂度:O(n^2) [移动次数没有变] */ public void binaryInsertSort(int[] array){ for(int i=1; i<array.length; i++){ int temp = array[i]; //通过一个循环选择最佳的分割点 int low = 0; int high = i - 1; while(low<=high){ int half = (low+high)/2; if(array[i]<array[half]){ high = half-1; }else{ low = half+1; } } for(int j=i-1; j>high; j--){ array[j+1]=array[j]; } array[high+1]=temp; } }
2路插入排序算法:在折半插入排序的基础上再改进,使用与原始数组大小的数组作为辅助空间,旨在减少记录的移动次数。
注意:如果当选择的第一个元素为数组中最大或者最小的元素的时候,这种排序方法会退化。
1 /* 2 * 二路插入排序 3 * 目的:为了减少移动次数 4 * 额外消耗:需要n个存储空间 5 */ 6 public int[] tInsertSort(int[] array){ 7 int[] cArray= new int[array.length]; 8 int start=0,end=array.length-1; 9 int temp = array[0]; 10 11 for(int i=1; i<array.length; i++){ 12 if(array[i]<=temp){ 13 if(cArray[start]==0){ 14 cArray[start]=array[i]; 15 }else{ 16 int j=start; 17 for(; j>=0&&array[i]<cArray[j]; j--){ 18 cArray[j+1]=cArray[j]; 19 } 20 cArray[j+1]=array[i]; 21 start++; 22 } 23 24 }else{ 25 if(cArray[end]==0){ 26 cArray[end]=array[i]; 27 }else{ 28 int k=end; 29 for(;k<cArray.length&&array[i]>cArray[k];k++){ 30 cArray[k-1]=cArray[k]; 31 } 32 cArray[k-1]=array[i]; 33 end--; 34 } 35 } 36 } 37 cArray[++start]=temp; 38 39 return cArray; 40 }
表插入排序方法:减少记录的移动,但是时间复杂度依旧不变
1 /* 2 * 表插入排序 3 * 目的:为了减少移动的次数 4 */ 5 public void tableInsertSort(DataItem[] array){ 6 for(int i=2;i<array.length;i++){ 7 int s=0; 8 while(array[array[s].getNext()].getVal()<array[i].getVal()){ 9 s=array[s].getNext(); 10 } 11 array[i].setNext(array[s].getNext()); 12 array[s].setNext(i); 13 } 14 }
希尔排序:又称缩小增量排序,在时间效率上该算法有所提高。
使用增量数组,来按照间隔来对数组中的元素进行排序。
关于增量数组的选择:还没有统一的定论,当inc[k]=2t-k+1+1,其中t为排序趟数,1<=k<=t<=log2(n+1)的时候,希尔排序的时间复杂度为O(n3/2).
1 /* 2 * 希尔排序 3 * 使用一个增量数组,按照数组中的值跳着对数组中的值进行排序 4 */ 5 public void shellSort(int array[],int[] incArray){ 6 for(int i=0; i<incArray.length; i++){ 7 incrementSort(array,incArray[i]); 8 } 9 } 10 11 public void incrementSort(int[] array, int inc){ 12 //如果修改成i++的话,依然是可以的,这个操作就是多多个序列进行的 13 //5-0 6-1 7-2 8-3 9-4 10-5 14 15 for(int i=inc; i<array.length; i++){ 16 if(array[i]<array[i-inc]){ 17 int temp=array[i]; 18 array[i]=array[i-inc]; 19 int j=i-2*inc; 20 for(;j>=0&&temp<array[j]; j-=inc){ 21 array[j+inc]=array[j]; 22 } 23 array[j+inc]=temp; 24 } 25 } 26 }