直接插入排序
直接插入排序简介
直接插入排序(Straight Insertion Sort)的基本思想是:把n
个待排序的元素看成一个有序表和一个无序表。开始的时候有序表中只包含1个元素,无序表中只包含n-1
个元素,排序的过程每次从无序表中选取第一个元素,将它插在有序表中的适当的位置,构造新的有续表,重复n-1
次上述过程,直到排序完成。
以数组{38,65,97,76,13,27,49}为例,直接插入排序的具体步骤如下:
第1步插入38之后:[38],65,97,76,13,27,49
第2步插入38之后:[38,65],97,76,13,27,49
第3步插入38之后:[38,65,97],76,13,27,49
第4步插入38之后:[38,65,76,97],13,27,49
第5步插入38之后:[13,38,65,76,97],27,49
第6步插入38之后:[13,27,38,65,76,97],49
第7步插入38之后:[13,27,38,49,65,76,97]
从上面的排序过程可以看到,我们把数组分成有序区和无序区,我们所做的工作只有两步:
- 取出无序区中的第一个数,并找出它在有序区当中对应的位置
- 将无序去的数据插入到有序区,如果有必要就对有序区中的相关数据进行移位操做。
下面上代码:
import java.io.*;
public class InsertSort
{
public static void insertSort(int[] array){
if (array.length <= 0)
return;
int i = 0, j = 0, k = 0, n = array.length;
for(i = 1; i < n; i ++){//从1开始是默认数组中第一个元素是有序区中的
//为array[i]在前面的array[0...i-1]有序区间中找一个合适的位置
for(j = i-1; j >= 0; j --) {
if(array[j] < array[i])
break;
}
//如找到了一个合适的位置
if(j != i-1) {
//将比a[i]大的数据向后移
int tmp = array[i];
for(k = i-1; k > j; k--) {
array[k+1] = array[k];
}
//将a[i]放到正确位置上
array[k+1] = tmp;
}
}
}
public static void main (String[] args) {
int[] array = {38,65,97,76,13,27,49};
insertSort(array);
for(int i: array)
System.out.println(i);
}
}
从上面可以看出我们是先查找位置,然后才进行移位,其实可以稍微的改进一下,边查找边移位,这样虽然没有减少时间复杂度,但是过程看起来更加的简洁:
public static void insertSortChange(int[] array){
if (array.length <= 0) {
return;
}
for (int i = 1; i < array.length; i++) {
int tmp = array[i];
int j = i;
if (array[j-1] > tmp) {
while (j >= 1 && array[j-1] > tmp ) {
array[j] = array[j-1];
j--;
}
}
array[j] = tmp;
}
}
直接插入排序的时间复杂度和稳定性
直接插入排序时间复杂度
直接插入排序的时间复杂度是O(N2)。
假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?N-1!因此,直接插入排序的时间复杂度是O(N2)。
直接插入排序稳定性
直接插入排序是稳定的算法,它满足稳定算法的定义。
算法稳定性 -- 假设在数列中存在a[i]=a[j],若在排序之前,a[i]在a[j]前面;并且排序之后,a[i]仍然在a[j]前面。则这个排序算法是稳定的!