一.直接插入排序:
原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。
最优复杂度:当输入数组就是排好序的时候,复杂度为O(n),而快速排序在这种情况下会产生O(n^2)的复杂度。
最差复杂度:当输入数组为倒序时,复杂度为O(n^2)
插入排序比较适合用于“少量元素的数组”。
int* InsertSort(int a[] , int n) {
for(int i = 1; i < n ; i++) {
if(a[i] < a[i-1]) {
int tmp = a[i];
int j = i-1;
while(j >= 0 && tmp < a[j]){
a[j+1] = a[j];
j--;
}
a[j+1] = tmp;
}
}
return a;
}
二.希尔排序
基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至为1,最后使用直接插入排序完成排序。
/**
* 直接插入排序的一般形式
*
* @param int dk 缩小增量,如果是直接插入排序,dk=1
*
*/
void ShellInsertSort(int* a , int n ,int dk) {
for(int i = dk ; i < n ;i++) {
if(a[i] < a[i-dk]){
int tmp = a[i];
int j = i-dk;
while(j >= 0 && tmp < a[j]) {
a[j+dk] = a[j];
j-=dk;
}
a[j+dk] = tmp;
}
}
}
/**
* 先按增量d(n/2,n为要排序数的个数进行希尔排序
*
*/
void ShellSort(int* a ,int n) {
int dk = n/2;
while(dk >=1) {
ShellInsertSort(a , n ,dk);
dk=dk/2;
}
}