1. 问题描述
2. 算法思想
希尔排序又称“缩小增量排序”,是对直接插入排序的改进算法。对待排序记录先做“宏观”调整,再做“微观”调整。
逐次根据不同增量将待排序记录序列分割成不同组,分别对其进行直接插入排序,最后取增量为1,对全体记录进行直接插入排序。
出发点:待排序记录序列按关键字基本有序时,直接插入排序效率较高;当待排序记录数n较小时,直接插入排序比较快。
3. C++实现
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
const int MAXSIZE = 20;
typedef struct RecordType{
KeyType key;
InfoType otherinfo;
}RecordType;
typedef struct SqList{
RecordType r[MAXSIZE];
int length;
}SqList;
// 一趟希尔排序
void shell_insertion(SqList &L, int dk)
{
for (int i=dk; i<L.length; ++i)
{
RecordType record = L.r[i];
int j = i - dk;
while ( j>=0 && LT(record.key, L.r[j].key) )
{
L.r[j+dk] = L.r[j];
j -= dk;
}
L.r[j+dk] = record;
}
}
// 希尔排序,dlta数组中保存的是增量序列
void shell_sort(SqList &L, int dlta[], int n)
{
for (int i=0; i<n; ++i)
shell_insertion(L, dlta[i]);
}
4. 算法复杂度分析
时间复杂度:与增量序列的选取有关,比 好,可达
。
空间复杂度为 ,此算法是原地排序的。
不稳定排序算法。
Shell排序的执行时间依赖于增量序列。
好的增量序列的共同特征:
① 最后一个增量必须为1;
② 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。