如同冒泡排序一样,插入排序也是算法课入门必谈之经典。那么两者的差异在哪里呢?
算法思想:
逐个拿出未排序元素和已经排好序的序列进行比较,找到合适的位置插入该元素,这个插入的操作会造成插入点之后的元素移动。
示例程序:
#define SWAP(A, B) do{(A) ^= (B); (B) ^= (A); (A) ^= (B);} while(0)
void _insert_sort(int array[], int left, int right) {
int i, j, tmp;
//先进行一次遍历,找出最小元素放在数组头部
for(i = right; i > left; i--) {
if(array[i] < array[i - 1]) {
SWAP(array[i], array[i - 1]);
}
}
//开头两元素已组成有序序列,故循环从第三个元素起
for(i = left + 2; i <= right; i++) {
j = i;
tmp = array[i];
while(tmp < array[j - 1]) {
SWAP(array[j], array[j - 1]);
j--;
}
array[j] = tmp;
}
}
void insert_sort(int array[], int len) {
_insert_sort(array, 0, len - 1);
}
复杂度分析:
内层循环执行次数的期望为(n-i)/2,其中i = n-1, n-2, ..., 2,外部循环次数为n,所以总共进行的比较次数为n^2/4;元素移动次数为n^2/4,在最坏情况下为n^2/2;由此可得其时间复杂度为O(n^2),空间复杂度为O(1)
重要性质:
1、稳定排序
2、适合处理给定有序序列,向其中添加少数元素的情况
3、原始序列的有序度越高,排序效率越高