Java排序算法——插入排序

一、插入排序的原理:
插入排序(英语:Insertion Sort)的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
举一个例子:对“54180”进行一个由小到大的排序
1、先取出一个5,因为只有一个数字,所以无需排序。
2、再取出4,此时排序完成的序列是5,要把4和5组成一个由小到大的序列,所以将4插入5的前面。
3、再取出1,此时排序完成的序列是45,如果要将一个数字插入一个由小到大的序列中,那么我们只需要从头至尾去寻找第一个比要插入数字大的数字将数字放在这个第一个比它大的数字前面,第一个比1大的数字是4,所以1插到4的前面
4、取出8,此时排序完成的数列是145,前面没有比8大的数字,所以8放到最后一个
5、取出0,此时完成排序的数列是1458,前面比0大的第一个数字是1,所以0插到1的前面
排序完成:01458
总结:重点操作在于提取出数据之后利用以及排好序的数列直接的数据关系来进行插入。
二、代码示范

public static class TestDemo{
    public static void insertSort(int[] array){
        if(array==null||array.length==0){
            return;
        }
        for(int i=0;i<array.length;i++){
            int tmp=array[i];//array[i]相当于待排序数据
            int j=0;
            for(;j<i;j++){
            //array[i]被提取出来之后是要和前边已经排好序的数据比较,故j
                if(array[j]>tmp){
                    break;
                  //这边break的原因是,有另外一种可能就是序列里没有大于j的数字
                  //此时j等于i也会导致跳出循环,所以用break直接跳出
                  //便于在后续直接同时处理两种情况
                }
            }
            //挪动数据
            for(k=i-1;k>=j;k--){
            //挪动数据是从i向前去找地方插入的,而j表示是找到的位置
                array[k+1]=array[k];
                //j位置之后的数据统一向后移动一个
            }
            //放数据
            array[j]=tmp;
            //把i的数据放到j的位置里
        }
    }
}

三、插入排序的分析:
1、空间复杂度:o(1)
2、时间复杂度:o(n^2)
3、算法稳定性:稳定
插入排序具有着,序列越有序,排序越快的特点

四、插入排序的优化:
“从前往后找第一个比待排序数据大的数据”从实质上是等于“从后往前找第一个比待排序数据小的数据”
代码:

for(int i=0;i<array.length;i++){
    int tmp=array[i];
    int j;
    for(j=i-1;j>=0;j--){
    //找数据和挪数据放在一起
        if(array[j]<=tmp){
            break;
        }else{
            //挪数据
            array[j+1]=array[j];
            //j位置的数据开始向后移动腾位置
        }
    }
    //放数据
    array[j+1]=tmp;
    //弹出时,有两种可能
    //1、正常弹出,此时找到j<=tmp,tmp要放到j后边,也就是j+1的位置
    //2、tmp是最小元素,此时弹出时j=-1,tmp是最小元素,要放到最前面,也是j+1
}

插入排序优化后:数据越有序,时间复杂度越低.当数据完全有序时,时间复杂度降低至O(n)

你可能感兴趣的:(Java数据结构与算法)