Fork me on GitHub
插入排序及其扩展

插入排序及其扩展

校园时光不多,准备找工作,多看点东西增加知识,为自己助力!加油!

插入排序:简单的排序方法

基本的操作:将一个新的记录插入到已经排好序的有序数组中

影响时间复杂度的因素:记录间的比较与移动

原始的插入排序算法:时间复杂度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     }
复制代码

 

 

 
 
posted on 2013-07-09 17:42  HackerVirus  阅读(195)  评论(0编辑  收藏  举报