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

xiaoxiao2021-02-28  102

基本思想

假设待排序的记录存放在数组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; } } } }

算法分析

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

最坏情况:逆序 每次从无序区取出第一个元素,首先需要与有序区最后一个元素比较一次,然后继续从有序区的最后一个元素比较,直到比较到有序区第一个元素,然后插入到有序区首位置。 每次从无序区取出第一个元素,移动放到拷贝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)。

排序稳定性

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

转载请注明原文地址: https://www.6miu.com/read-32008.html

最新回复(0)