算法
基础算法
插入排序(直接插入排序)
基本思想:插入排序是指在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序。
排序流程图
算法实现(java)
public static void main(String[] args) {
int[] array = {1, 4, 2, 3, 9, 6, 5};
int[] array2 = {8, 0, 1, 4, 2, 3, 7};
int[] array3 = {-2, 3, 1, 0, 4, 5, 2};
insertSort(array);
insertSort2(array2);
insertSort3(array3,array3.length-1);
System.out.println(Arrays.toString(array));
System.out.println(Arrays.toString(array2));
System.out.println(Arrays.toString(array3));
}
public static void insertSort(int[] array) {
for (int i = 1; i <= array.length - 1; i++) {
int temp = array[i];
for (int j = i - 1; j >= 0; j--) {
if (temp < array[j]) {
array[j + 1] = array[j];
} else {
array[j + 1] = temp;
break;
}
}
}
}
public static void insertSort2(int[] array) {
for (int i = 1; i <= array.length - 1; i++) {
int temp = array[i];
int j = i - 1;
while (j >= 0 && array[j] > temp) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = temp;
}
}
/**
* 递归实现
* @param array
* @param end
*/
public static void insertSort3(int[] array, int end) {
if (end == 1) {
return;
}
insertSort3(array, end - 1);
int index = end - 1;
int temp = array[end];
while (index >= 0 && temp < array[index]) {
array[index + 1] = array[index--];
}
array[index + 1] = temp;
}
}
运行结果
算法分析
-
时间复杂度
在插入排序中,当待排序数组是有序时,是最优的情况,只需当前数跟前一个数比较一下就可以了,这时一共需要比较N- 1次,时间复杂度为O(n)。最坏的情况是待排序数组是逆序的,此时需要比较次数最多,总次数记为:1+2+3+…+N-1,所以,插入排序最坏情况下的时间复杂度为O(n²) 。
平均来说,A[1..j-1]中的一半元素小于A[j],一半元素大于A[j]。插入排序在平均情况运行时间与最坏情况运行时间一样,是输入规模的二次函数 。
空间复杂度
插入排序的空间复杂度为常数阶O(1).
稳定性分析
如果待排序的序列中存在两个或两个以上具有相同关键词的数据,排序后这些数据的相对次序保持不变,即它们的位置保持不变,通俗地讲,就是两个相同的数的相对顺序不会发生改变,则该算法是稳定的;如果排序后,数据的相对次序发生了变化,则该算法是不稳定的。关键词相同的数据元素将保持原有位置不变,所以该算法是稳定的。
应用分析
插入排序适用于已经有部分数据已经排好,并且排好的部分越大越好。一般在输入规模大于1000的场合下不建议使用插入排序。