希尔排序简介
希尔排序(Shell’s Sort)是插入排序的一种又称“缩小增量排序”(Diminishing Increment Sort),是直接插入排序算法的一种更高效的改进版本,时间复杂度为O(n^2)。
希尔排序的模拟过程可以看链接:ShellSortion
在看具体代码实现之前,需要先看我之前的文章中关于插入排序的代码实现:插入排序
实现过程
为了比较容易地理解插入排序,我们可以列出一组数据,比如:
1,5,4,3,7
我列出了两种方法分别说明插入排序的实现过程,你可以选择自己喜欢的方法:
第一种
对于希尔排序算法来说:
1. 计算步长(间隔):4/2=2, 分出了两个过程:
(1). 根据步长,取出数据:1, 4, 7
,进行插入排序:
1, 4, 7
(2) 根据步长,取出数据:‘5, 3’,进行插入排序:
5,3
完成上面两个过程后,现在的数据为1,3,4,5,7
2. 计算步长:4/4=1, 根据步长, 取出数据:1,3,4,5,7
,进行插入排序:
1,3,4,5,7
第二种
分析以上过程,我们发现希尔排序有两个要素:
1. 进入插入排序前,我们需要得到步长,还有起始地址。
2. 步长需要通过数据长度/2得到。
代码实现
首先我们需要对插入排序进行一些修改:
void pushFront(int *a, const int length, const int key, const int dk) {
//将所有a[j]到a[length]都往后推一格
int tmp = a[length];
for (int i = length; i >key; i = i - dk) {
a[i] = a[i- dk];
}
a[key] = tmp;
};
void insertSort(int *a, const int length, const int dk, const int div) {
//dk 步长, div 初始地址
for (int i = div; i < length; i = i + dk) {
for (int j = div; j < i; j = j + dk) {
if (a[i] < a[j]) {
pushFront(a, i, j, dk);
break;
}
}
print(a, length);
}
}
相比之前的插入排序,我们加入了步长和起始地址,所以我们只需要计算完成步长和初始地址的迭代计算即可:
void shellSort(int *a, const int length) {
for (int i = 2; length / i > 0; i = i * 2) {
int dk = length / i;
for (int div = 0; div < length / i + 1; div++) {
insertSort(a , length, dk, div);
}
}
}
完整的代码:
#include <stdio.h>
void print(const int *a, const int length) {
int i;
for (i = 0; i<length; i++) {
printf("%d ", a[i]);
}
putchar('\n');
}
void pushFront(int *a, const int length, const int key, const int dk) {
//将所有a[j]到a[length]都往后推一格
int tmp = a[length];
for (int i = length; i >key; i = i - dk) {
a[i] = a[i- dk];
}
a[key] = tmp;
};
void insertSort(int *a, const int length, const int dk, const int div) {
//dk 步长, div 初始地址
for (int i = div; i < length; i = i + dk) {
for (int j = div; j < i; j = j + dk) {
if (a[i] < a[j]) {
pushFront(a, i, j, dk);
break;
}
}
print(a, length);
}
}
void shellSort(int *a, const int length) {
for (int i = 2; length / i > 0; i = i * 2) {
int dk = length / i;
for (int div = 0; div < length / i + 1; div++) {
insertSort(a , length, dk, div);
}
}
}
void main() {
const int length = 5;
int my_array[5] = { 1,5,7,3,4};
print(my_array, length);
shellSort(my_array, length);
print(my_array, length);
}
代码精简
void SelectSort(int r[],int length){
int i ,j , min ,max, tmp;
for (i=0 ;i < length/2;i++){
min = i;
max = i;
//find minimum
for (j= i+1; j< length-i; j++){
if (r[j] > r[max]){
max = j ;
continue;
}
if (r[j]< r[min]){
min = j ;
}
}
tmp = r[i]; r[i] = r[min]; r[min] = tmp;
tmp = r[length-i-1]; r[length-i-1] = r[max]; r[max] = tmp;
}
}