插入排序:
适合数据量比较小的排序(其工作机理类似于我们打牌时,整理手中的牌一样)。最坏的情况下运行时间是O(n2)(表示n的平方),最好的情况下运行时间是O(n)
具体的代码如下:
插入排序:
public static void insertion_sort (int a[]) {
for (int i = 1;i < a.length;i++) {
int key = a[i];
int j = i - 1;
while (j >= 0 && a[j] > key) {
a[j+1] = a[j];
j--;
}
a[j+1] = key;
}
}
我们根据插入排序的原理可以知道:a[0...i-1]之间的元素是排好序的,上面的插入排序在查找key的插入位置时使用的是线性查找。
自然而然想到可以使用二分查找来来实现对数级的查找。最坏的运行时间是O(nlgn)其中n是问题的输入规模;
具体的代码如下:
简单优化后的插入排序。
public static void insertion_sort2 (int a[]) {
for (int i = 1;i < a.length;i++) {
int key = a[i];
int inserP = find (a,0,i-1,key);
for (int j = i;j > inserP;j-- ) {
a [j] = a[j-1];
}
a[inserP] = key;
}
}
public static int find (int a[],int start,int end,int key) {
int middle = 0;
while (start <= end) {
middle = (start + end ) / 2;
if (a[middle] == key) {
return middle;
}else if (a[middle] > key) {
end = middle - 1;
}else {
start = middle + 1;
}
}
return start;
}
当数据量比较大的时候,时间为对数级的算法时间增长量比平方级慢。
更新:2013年8月31号 19:57
上面有关简单优化后的插入排序的最坏运行时间是错误的。
总体的运行时间不能改善为O(nlgn)。虽然二分查找的时间复杂度可以为lgn,但是存在插入数时数组移动的时间。