/**
* 插入排序:
* 将一个记录插入已经排好序的新序列
*
* 1,当初始序列为正序时,只需要外循环n-1次,每次进行一次比较,无需移动元素。
* 此时比较次数(C _{min})和移动次数(M_{min})达到最小值。
* C _{min}=n-1
* M_{min}=0
* 此时时间复杂度为O(n)。
* 2,当初始序列为反序时,需要外循环n-1次,
* 每次排序中待插入的元素都要和[0,i-1]中的i个元素进行比较且要将这i个元素后移i次,
* 加上tmp=arr[i]与arr[j]=temp的两次移动,每趟移动次数为i+2,
* 此时比较次数和移动次数达到最大值。
* C_{max} = 1+2+...+(n-1) = n(n-1)/2=O(n^2)
* M_{max} = (1+2)+ (2+2)+.....+(n-1+2)=(n-1)(n+4)/2=O(n^2)
* 此时时间复杂度O(n)
* 3,在直接插入排序中只使用了i,j,tmp这三个辅助元素,与问题规模无关,空间复杂度为O(1)。
* 4,相同元素的相对位置不变,如果两个元素相同,插入元素放在相同元素后面。是一种稳定排序
* @param arr
*/
public static void charuSort(int[] arr) {
int tmp;
for (int i = 1; i < arr.length; i++) {
// 顺序
if(arr[i]<arr[i-1]){
tmp = arr[i];
for (int j = i; j >= 0 ; j--) {
// 后一个比前一个值大,交换位置,这已经是有序序列
if(j > 0 && arr[j-1]>tmp){
arr[j] = arr[j-1];
}else{//找到tmp的位置
arr[j] = tmp;
break;
}
}
}
}
}
排序方法 | 平均情况 | 最好情况 | 最坏情况 | 辅助空间 | 稳定性 |
冒泡排序 | N2 | n | N2 | 1 | 稳定 |
选择排序 | N2 | N2 | N2 | 1 | 不稳定 |
插入排序 | N2 | n | N2 | 1 | 稳定 |
希尔排序 | N*logn~n2 | N1.3 | N2 | 1 | 不稳定 |
堆排序 | N*logn | N*logn | N2 | 1 | 不稳定 |
归并排序 | N*logn | N*logn | N*logn | N | 稳定 |
快速排序 | N*logn | N*logn | N2 | 1 | 不稳定 |