插入排序
插入排序基本思想:每一趟将一个待排序的元素,按其关键字值的大小插入到已经排过序的有序区中的适当位置,直到全部插入完成为止。不同插入排序算法的最根本的不同点是根据什么规则去找新元素的插入点,直接插入排序是依次寻找,希尔排序缩小增量再使用直接插入排序。
直接插入排序
- 基本思想
直接插入排序是一种最简单的排序方法,它就是依次将无序区中的每一个元素插入到一个有序区中去。 - 例子
{4,5,1,2,8,6,7,3,10,9}
取无序区间的第一个,从右向左扫描有序区间比较,方括号内可视为有序区间。
第一次:[4],5,1,2,8,6,7,3,10,9
第二次:[4,5],1,2,8,6,7,3,10,9
第三次:[1,4,5],2,8,6,7,3,10,9
第四次:[1,2,4,5],8,6,7,3,10,9
第五次:[1,2,4,5,8],6,7,3,10,9
第六次:[1,2,4,5,6,8],7,3,10,9
第七次:[1,2,4,5,6,7,8],3,10,9
第八次:[1,2,3,4,5,6,7,8],10,9
第九次:[1,2,3,4,5,6,7,8,10],9
第十次:[1,2,3,4,5,6,7,8,9,10] - 算法分析
直接插入排序算法的空间复杂度为O(1)。
最好的情况,要比较的无序序列原本就是顺序有序的,那么要比较的次数是n-1,移动了0次,时间复杂度O(n)。
最坏的情况,要比较的无序序列原本就是逆序有序的,那么要比较的次数是(n+2)(n-1)/2,移动的次数(n+4)(n-1)/2,时间复杂度O(n²)。
直接插入排序的平均复杂度为O(n²)。
直接插入排序是稳定的。 - Java代码实现
package com.gray;
import java.util.Arrays;
public class InsertionSort {
public static void main(String args[]) {
int a[] = {4, 5, 1, 2, 8, 6, 7, 3, 10, 9};
insertionSort(a);
System.out.println("排序后:" + Arrays.toString(a));
}
private static void insertionSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
int temp = arr[i];
int j = i - 1;
while (j >= 0 && temp < arr[j]) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
}
}
希尔排序
- 基本思想
把记录按下标的一定增量d分组,对每组记录采用直接插入排序方法进行排序(比较的方法其实也是直接插入排序),随着增量逐渐减小,所分成的组包含的记录越来越多,到增量的值减少到1时,整个数据合成一组,构成一组有序记录。 - 例子
{4,5,1,2,8,6,7,3,10,9}
对选出来的序列分别做直接插入排序
直接插入排序后得出最终排序结果[1,2,3,4,5,6,7,8,9,10] - 算法分析
希尔排序的空间复杂度为O(1)。
希尔排序在最坏的情况下的运行时间是O(n²),平均时间复杂度为O(n^1.3)。希尔排序对于多达几千个数据项的,中等大小规模的数组排序表现良好。希尔排序不像快速排序和其它时间复杂度为O(nlog2n)的排序算法那么快,因此对非常大的文件排序,它不是最优选择。但是,希尔排序比选择排序和插入排序这种时间复杂度为O(n²)的排序算法还是要快得多,并且它非常容易实现。它在最坏情况下的执行效率和在平均情况下的执行效率相比没有差很多。
此外希尔排序是不稳定的。 - Java代码实现
package com.gray;
import java.util.Arrays;
public class ShellSort {
public static void main(String args[]) {
int a[] = {4, 5, 1, 2, 8, 6, 7, 3, 10, 9};
shellSort(a);
System.out.println("排序后:" + Arrays.toString(a));
}
private static void shellSort(int[] arr) {
int gap = arr.length / 2;
while (gap > 0) {
for (int i = gap; i < arr.length; i++) {
int temp = arr[i];
int j = i - gap;
while (j >= 0 && temp < arr[j]) {
arr[j + gap] = arr[j];
j = j - gap;
}
arr[j + gap] = temp;
j = j - gap;
}
gap = gap / 2;
}
}
}