插入排序

  说到插入排序,想必大家都不陌生,这里简要的介绍一下。首先,它的思想是这样的,有一组数据,先取出第一个数,把它作为一个有序的数组。然后接着再取一个数,将它放到那个有序数组里的一个合适位置,使得这个数组仍然有序。如此循环下去,每次从原数组中取出一个数,放到有序的数组里。当所有数据都取完了,这个排序也就完成了。

  用文字描述可能有些抽象,下面给出一个实例,例如对数组 {32,12,54,32,15} 进行排序。

  首先将第一个元素,也就是32,看作是一个有序的序列。可以这样表示 {32|12,54,32,15} (里面那个竖线分割了有序序列和待排序的数组)

  接下来,取待排序数组中的第一个元素,也就是12,因为它比32小,所以将它放到32的前面,于是有这样的表示 {12,32|54,32,15}。

    基本过程就是这样,如此反复下去,知道待排序数组中的数据,都插入到有序序列的合适位置,排序就完成了。

  对上面那个例子排序的全过程如下:

  {32,12,54,32,15} => {32|12,54,32,15} => {12,32|54,32,15}

  =>{12,32,54|32,15} => {12,32,32,54|15} => {12,15,32,32,54}

 

方法明白了,下面就给出代码,一个C语言升序排列的实现如下:

void insertion_sort(int *arr,int len){
    
    
int i,j,tmp;

    
for(i = 1;i < len;i++){
        
        j 
= i - 1;
        tmp 
= arr[i];
        
while(j >= 0 && arr[j] > tmp){
            arr[j 
+ 1= arr[j];
            j
--;
        }
        arr[j 
+ 1= tmp;
    }
}

 

  很容易看出来,这个算法有两层循环,插入排序的时间复杂度平均为O(n2),当问题规模越来越大的时候,插入排序的效率就会很低,所以插入排序之适用于问题规模较小的情况,至于n为多少才适用插入排序,在jdk源代码中有这样一段,应该可以作为一个参考。

  这个是java.util.Arrays的sort()方法内部的代码。

 

 

    /**
     * Sorts the specified sub-array of longs into ascending order.
     
*/
    
private static void sort1(long x[], int off, int len) {
    
// Insertion sort on smallest arrays
    if (len < 7) {
        
for (int i=off; i<len+off; i++)
        
for (int j=i; j>off && x[j-1]>x[j]; j--)
            swap(x, j, j
-1);
        
return;
    }
        
//其他部分省略
         
//
        
//
        
//
        
//
    }

 

  可以看到,在jdk中,只有长度小于7的数组才会应用插入排序,随着问题规模的增大,采用合并排序等算法,才是比较合适的。

posted @ 2009-11-06 00:03  Springfield  阅读(2332)  评论(6编辑  收藏  举报