直接插入排序介绍
直接插入排序的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。
怎么理解呢?就是将n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只有一个元素,无序表中有n-1个元素,排序过程中每次从无序表中取出第一个元素,将其插入到有序表中的指定位置,使之成为一个新的有序表,重复n-1次可完成排序过程。
直接插入排序流程说明
具体流程如下:
- 首先比较数组的前两个数据,并排序;
- 比较第三个元素与前两个排好序的数据,并将第三个元素放入适当的位置;
- 比较第四个元素与前三个排好序的数据,并将第四个元素放入适当的位置;
… - 直至把最后一个元素放入适当的位置。
代码实现:
public class InsertSort {
//置换
public void swap(int[] elem, int i, int j) {
int temp = elem[i];
elem[i] = elem[j];
elem[j] = temp;
}
public void insertSort(int[] elem) {
int i, j;
for (i = 2; i < elem.length; i++) {
if(elem[i] < elem[i - 1]) { //需要将elem[i]插入到有序子表
elem[0] = elem[i]; //设置哨兵
for (j = i - 1; elem[j] > elem[0]; j--) {
elem[j + 1] = elem[j]; //记录后移
}
elem[j + 1] = elem[0]; //插入到正确位置
}
}
}
public static void main(String[] args) {
InsertSort s = new InsertSort();
// int[] elem = {0, 9, 1, 5, 8, 3, 7, 4, 6, 2};
int[] elem2 = {0, 5, 3, 4, 6, 2};
s.insertSort(elem2);
for (int i = 1; i < elem2.length; i++) {
System.out.print(elem2[i] + ", ");
}
}
}
i从2开始的意思是我们假设elem[1]=5已经放好位置,后面的数据元素就是插入到它的左侧还是右侧的问题。
对于初始数据:{5, 3, 4, 6, 2}。
- 首先比较5和3的大小,3小,位置互换,第一轮排序后,顺序为:[3, 5, 4, 6, 2]。
- 对于第三个数据4,其大于3,小于5,将其插入3和5之间,顺序依旧为:[3, 4, 5, 6, 2]。
- 对于第四个数据6,其大于3,4,5,不需要插入,位置不变,顺序为:[3, 4, 5, 6, 2]。
- 对于第五个数据2,其小于于3,将其插入到3的前面,顺序为:[2, 3, 4, 5, 6,]。
直接插入排序复杂度分析
从空间上看只需要一个哨兵的辅助空间。
当最好的情况下,也就是表本身就是有序的,那么我们比较次数共计n-1()次,因为每次都是elem[i]>elem[i -1],所以没有移动记录,时间复杂度为O(n)
当最坏的情况下,即逆序情况下,此时需要比较次,而记录的移动次数也达到最大值次
如果排序记录是随机的,那么根据概率相同的原则,平均比较和移动次数约为次。因此我们得出直接插入排序的时间复杂度为O()。
同样的复杂度,直接插入排序比冒泡和简单选择排序性能要好。