3、插入排序

0

算法描述

插入排序是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

依次选择一个待排序的数据,插入到前边已排好序的序列中。

  1. 把待排序的数组分成已排序和未排序两部分,初始的时候把第一个元素认为是已排好序的。
  2. 从第二个元素开始,在已排好序的子数组中寻找到该元素合适的位置并插入该位置。
  3. 重复上述过程直到最后一个元素被插入有序子数组中。

稳定性

由于只需要找到不大于当前数的位置而并不需要交换,因此,直接插入排序是稳定的排序方法。

性能

时间复杂度为O(N^2),空间复杂度为O(1)。算法是稳定的,比较次数和交换次数都与初始序列有关。

优化

直接插入排序每次往前插入时,是按顺序依次往前找,可在这里进行优化,往前找合适的插入位置时采用二分查找的方式,即折半插入。 

折半插入排序相对直接插入排序而言:平均性能更快,时间复杂度降至O(NlogN),排序是稳定的,但排序的比较次数与初始序列无关,总是需要foor(log(i))+1次排序比较。

适用场景

当数据基本有序时,采用插入排序可以明显减少数据交换和数据移动次数,进而提升排序效率。

插入排序由于O( n2 )的复杂度,在数组较大的时候不适用。但是,在数据比较少的时候,是一个不错的选择,一般做为快速排序的扩充。例如,在STL的sort算法和stdlib的qsort算法中,都将插入排序作为快速排序的补充,用于少量元素的排序。又如,在JDK 7 java.util.Arrays所用的sort方法的实现中,当待排数组长度小于47时,会使用插入排序。

import java.util.*;

public class InsertionSort {
    public int[] insertionSort(int[] A, int n) {
        for(int i=0;i<n;i++){
         for(int j=i;j>0;j--){
           if(A[j-1]>A[j]){
             int temp=A[j-1];
             A[j-1]=A[j];
             A[j]=temp;
           }
         }
       }
         return A;
    }
}