插入排序

  插入排序的基本思想是:每一趟将一个待排序的记录,按器关键字的大小插入到已经排好序的一组记录的适当位置上,直到所有待排序记录全部插入为止。

  例如,打扑克牌在抓牌的时要保证抓过的牌有序排列则每抓一张牌,就插入到合适的位置,直到抓完牌为止,即可得到一个有序序列。

  可以选择不同的方法在已排好序的记录中寻找插入位置。根据查找方法的不同,有多种插入排序方法,这里主要介绍直接插入排序。

直接插入排序

  直接插入排序(Straight  Insertion  Sort)是一种最简单的排序方法,其基本操作是将一条记录插入到已排好序的有序表中,从而得到一个新的、记录数量增1的有序表

算法步骤

  1)设待排序的记录放在数组中r[1...n]中,r[1]是一个有序序列。

  2)循环n-1次,每次使用顺序查找法,查找r[i](i=2,...n)在已排好序的序列r[1...i-1]中的插入位置,然后将r[i]插入表长为i-1的有序序列r[1...i-1],直接将r[n]插入表长为n-1的有序序列r[1...n-1],最后得到一个表长为n的有序序列

插入排序示意图

java代码的实现

package com.hxy.sort;

import java.util.Arrays;

public class InsertSort {
    public static void main(String[] args) {
        int[] arr ={49,38,65,97,76,13,27,49};
        System.out.println("排序之前的数组");
        System.out.println(Arrays.toString(arr));
        insertSort(arr);
        System.out.println("排序之后的数组");
        System.out.println(Arrays.toString(arr));
    }
    public static void insertSort(int[] arr){
        for (int i = 1; i<arr.length;i++){
            if(arr[i]<arr[i-1]){//若第i个元素小于第i-1个元素,移动有序序列, 如果大于的话则直接插入
                int temp = arr[i];//存储待插入的记录
                arr[i] = arr[i-1];
                int j = i-1;
                for(;j>=0&&temp<arr[j];j--){//判断条件
                    arr[j+1] = arr[j];
                }
                arr[j+1] = temp;// 将待插入的元素插到指定位置
            }
        }
    }
}

结果如下图所示

 动画示意图

 插入排序

时间复杂度

  对于整个排序过程需执行n-1趟,在最好的情况下(正序:待排序序列中记录按关键字非递减有序排列),总的移动比较次数达到最小值n-1,记录不需移动;最坏情况下(即待排序表为逆序),总的关键字比较次数为(n+2)(n-1)/2≈n^{2}/2,记录移动次数为(n+4)(n-1)/2≈n^{2}/2。若待排序序列中出现各种可能排列的概率相同,则可取上述最好情况和最坏情况的平均情况。在平均情况下,直接插入排序关键字的比较次数和记录移动次数均约为n^{2}/4。由此,直接插入排序的时间复杂度为O(n^{2}

空间复杂度

  直接插入排序只需要一个记录的辅助空间temp,所以空间复杂度为O(1)。

算法的特点

(1)稳定排序

(2)算法简单,且容易实现

(3)也适用于链式存储结构,只是在单链表上无需移动记录,只需修改相应的指针。

(4)更适合初始记录基本有序(正序)的情况,当初始记录无序,n较大时,此算法的时间复杂度较高,不宜采用

 

原文地址:https://www.cnblogs.com/huxiaoyang/p/12032004.html