直接插入排序
-
简介
插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。 -
基本思想
插入排序的基本思想是将一个待排序的数组分为两个部分,一部分是已经排好序的,另一部分是待排序的,然后将待排序的部分依次和已排序的部分进行比较,比较完毕再插入到正确的位置,然后插入位置之后的数据后移。在我看来现实生活中有一个最形象的事件可以说说插入排序的最好例子——打麻将时摸牌,每次从桌上摸到一张牌,就和自己已有的牌进行比较,然后放入,插入排序就是如此。 -
图解
-
代码实现
//按升序排列
public static void insertSort(int[] arr){
//待插入的数据
int insertVal = 0;
//待插入数据的下标
int insertIndex = 0;
for (int i = 1; i < arr.length; i++) {
insertVal = arr[i];
insertIndex = i;
while (insertIndex-1 >= 0&& insertVal < arr[insertIndex-1]){
//若待插入的值比前面的值小,那么前面的值就后移一位,给待插入的数据让位置
arr[insertIndex] = arr[insertIndex-1];
insertIndex--;
}
arr[insertIndex] = insertVal;
}
}
- 稳定性,时间复杂度
稳定性:
如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变, 从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。
时间复杂度:
在插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较N- 1次,时间复杂度为O(n)。
最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为O(n^2)。
平均来说,A[1…j-1]中的一半元素小于A[j],一半元素大于A[j]。插入排序在平均情况运行时间与最坏情况运行时间一样,是输入规模的二次函数 。 - 总结
通过对时间复杂度的分析,我们可以看出当待排序的数组长度不是很长的时候,且待排序数据的顺序比较简单的时候,使用插入排序是很好的,但是如果遇到很长的数组,且顺序为逆序时,时间复杂度将变成N^2,时间消耗很大,下一节将用希尔排序解决该问题。