插入排序:直接插入排序-Direct insertion sort

来源:互联网 发布:淘宝旺铺店招代码 编辑:程序博客网 时间:2024/05/19 00:42

基本思想

假设待排序的记录存放在数组R[0..n-1]中。初始时,R[0]自成1个有序区,无序区为R[1..n-1]。 从i=1起直至i=n-1为止,依次将R[i]插入当前的有序区R[0..i-1]中,生成含n个记录的有序区。

public class InsertSort {    public static void main(String[] args) {        // TODO Auto-generated method stub        int score[] = { 100, 69, 75, 87, 89, 90, 99, 67 };        sort(score);        for (int i : score) {            System.out.print(i + "\t");        }    }    public static void sort(int[] array) {        int tmp;        for (int i = 1; i < array.length; i++) {            tmp = array[i]; // array[i]的拷贝            // 如果右侧无序区第一个元素array[i] < 左侧有序区最大的array[i-1],            // 需要将有序区比array[i]大的元素向后移动。            if (array[i] < array[i - 1]) {                int j = i - 1;                while (j >= 0 && tmp < array[j]) { // 从右到左扫描有序区                    array[j + 1] = array[j]; // 将左侧有序区中元素比array[i]大的array[j+1]后移                    j--;                }                // 如果array[i]>=左侧有序区最大的array[i-1],或者经过扫描移动后,找到一个比array[i]小的元素                // 将右侧无序区第一个元素tmp = array[i]放到正确的位置上                array[j + 1] = tmp;            }        }    }}

算法分析

  1. 最好情况:有序
    通过直接插入排序的执行过程可以看到,如果待排序数组恰好为有序,则每次从大小为n-1的无序区数组取出一个元素,和有序区最后一个元素比较,一定是比最后一个元素大,需要插入到有序区最后一个元素的后面,也就是原地插入。
    可见,比较次数为n-1次,数组元素移动次数为0次。

  2. 最坏情况:逆序
    每次从无序区取出第一个元素,首先需要与有序区最后一个元素比较一次,然后继续从有序区的最后一个元素比较,直到比较到有序区第一个元素,然后插入到有序区首位置。
    每次从无序区取出第一个元素,移动放到拷贝tmp中,然后再将tmp与有序区元素比较,这个比较过程一共移动的次数为:有序区数组大小,最后还要将拷贝tmp移动插入到有序区的位置上。
    在这个过程中:
    有序区数组大小为1时,比较2次,移动3次;
    有序区数组大小为2时,比较3次,移动4次;
    ……
    有序区数组大小为n-1时,比较n次,移动n+1次。
    可见:
    比较的次数为:2+3+……+n = (n+2)(n-1)/2
    移动的此时为:3+4+……+n+1 = (n+4)(n-1)/2
    通过上面两种情况的分析,直接插入排序的时间复杂度为O(n2)。

空间复杂度

在直接插入排序的过程中,只用到一个tmp临时存放待插入元素,因此空间复杂度为O(1)。

排序稳定性

直接插入排序是稳定排序。

原创粉丝点击