插入排序是一种简单直观的排序方法,其基本思想是每次将一个待排序的记录按其关键字大小插入前面已排好序的子序列,直到全部记录插入完成。
目录
一、排序过程
二、代码
三、性能及稳定性分析
1.空间复杂度
2.时间复杂度
3.稳定性
一、排序过程
假设待排序表L[1...n]再某次排序过程中的某一时刻状态如下:
?
要将元素L(i)插入已有序的子序列 L[1...i-1],需要执行以下操作:
①:查找出L(i)在L[1...i-1]表中的插入位置k。
②:将L[k...i-1]中的所有元素依次后移一个位置。
③:将L(i)复制到L(k)。
示意图:
二、代码
代码未采用哨兵,采用的是temp中间变量。
public class InsertionSort {
public static void main(String[] args) {
int[] arr = {3, 6, 4, 1, 9, 5, 8, 7, 2};
System.out.println("排序前为:");
for (int i : arr) {
System.out.print(i + " ");
}
System.out.println();
insertsort(arr);
System.out.println("排序后为:");
for (int i : arr) {
System.out.print(i + " ");
}
}
public static void insertsort(int[] arr) {
int temp; //中间变量
int j; //后移的下标
for (int i = 1; i < arr.length; i++) { //外层循环,控制未排序的
if (arr[i] < arr[i - 1]) { //如果当前元素小于前一个元素,就得排序
temp = arr[i]; //将当前元素赋值给中间变量
for (j = i - 1; j >= 0 && temp < arr[j]; --j) { //内层循环,从后往前查找待插入的位置
arr[j + 1] = arr[j]; //将前面已排序的元素依次后移,直到需要后移的元素大于temp时停止
}
arr[j + 1] = temp; //最后复制到插入位置
}
}
}
}
?
?
结果:
?
三、性能及稳定性分析
1.空间复杂度
因为排序的整个过程中,仅在当前的数组中操作,没有使用另一个空数组,仅使用了常熟个辅助单元,因此时间复杂度为O(1)。
2.时间复杂度
在排序过程中,向有序子表中逐个地插入元素的操作进行了n-1趟,每趟操作都分为比较关键字和移动元素,而比较次数和移动次数取决于待排序表的初始状态。
- 在最好的情况下,表中元素已经有序,此时没插入一个元素,都只需比较一次而不用移动元素,因此时间复杂度为O(n)。
- 在最坏情况下,表中元素顺序刚好与排序结果中的元素顺序刚好相反(逆序),总的比较次数达到最大,为,总的移动次数也达到最大,为。
- 平均情况下,考虑待排序表中元素是随机的,此时可以取最好与最坏情况的平均值作为平均情况下的时间复杂度,总的比较次数与总的移动次数均为。
综上所以,直接插入排序算法的时间复杂度为O()。
3.稳定性
由于每次插入元素时总是从后向前先比较在移动,所以不会出现相同元素相对位置发生变化的情况,因为直接插入排序是一个稳定的排序方法。
?
|