直接插入排序
插入排序的思想是将数组分为已排序序列和未排序序列两部分,通过比较每次将未排序序列中的元素插入到已排序序列中。插入排序是稳定的时间复杂度为log(n^2)的原地排序算法。
未优化代码
void insertSort(int a* ,int n){
int tmp;
for(int i = 1; i < n; i ++){
int j = i - 1;
while(j > = 0){
if(a[i] < a[j]){
tmp = a[j];
a[j] = a[i];
a[i] = tmp;
}else{
break;
}
}
}
}
针对CPU优化后代码 - 减少访存次数,将标量用寄存器存储
void insertSort(int *a, int n){
int value, j; // a[i]用变量value代替
for(int i = 1; i < n; i ++){
value = a[i];
j = i - 1;
while(j >= 0){
if(value < a[j]){
a[j + 1] = a[j];
j --;
}else {
break;
}
}
a[j + 1] = value;
}
}
折半插入排序
折半插入排序是对直接插入排序的优化。优化点在于查找未排序元素在已排序序列中的插入位置时用到了折半查找算法。
代码
void insertSort_b(int *a, int n){
int value, j, low, high, mid;
for(int i = 1; i < n; i ++){
value = a[i];
low = 0;
high = i - 1;
//查找第一个大于value的元素
while(low <= high){
mid = low + ((high - low) >> 1);
if(a[mid] > value){
high = mid - 1;
}else {
low = mid + 1;
}
}
// 将元素后移
for(int j = i - 1; j >= high + 1; j ++){
a[j + 1] = a[j];
}
a[high + 1] = value;
}
}
希尔排序
希尔排序又称最小增量排序。希尔排序就是将要排序的顺序表分成若干的子表,对子表进行插入排序。希尔排序是不稳定的排序算法。
代码实现
void shellSort(int *a, int n){
int value, j;
for(int d = n / 2; d >= 1; d >>= 1){
for(int i = d; i < n - d; i ++){
value = a[i];
for(j = i - d; j >=0; j-=d){
if(a[j] > value){
a[j + d] = a[j];
}else{
break;
}
}
a[j + d] = value;
}
}
}