希尔排序的算法思想是分组直接插入排序,直接上例子:
对于一组数据 2,5,3,6,7,1,4,长度n为7,那么按n/2分组,第一次是分为3组,第二次1组。
第一次分组,数据间隔为3的分成一组,对每组数据进行直接插入排序:
组一:2,6,4,直接插入排序后为2,4,6
组二:5,7
组三:3,1
综合起来即为:2,5,3,4,7,1,6
第二次,间隔为1的分成一组,共一组:2,5,3,4,7,1,6,变成了直接插入排序,但这个数据序列已经是接近有序状态,所以排序过程比较快。
希尔排序是在直接插入排序基础上对算法复杂度的优化。
C++实现:
# include <iostream>
using namespace std;
#define TEST_ARRAY_LEN 11
//从小到大排序
void shell_sort(int test[], int len)
{
int i, step, k, temp;
int h = len;
do{
//设置增量
//h = h/2;
h = h / 3 + 1;
//h数即为希尔排序的组数,对每组进行直接插入排序,setp表示第几组,从0开始编号。
for(step = 0; step < h; step++)
{
//找到每组的数据,根据直接插入排序思想,第一个数据test[step]是默认排好序的。
for(i = step + h; i < len; i = i + h)
{
//对每组数据进行直接插入排序,如果test[k]大于temp,则向后挪h个位置,直到test[k]不大于temp,插入temp
temp = test[i];
for(k = i - h; k >= 0 && test[k] > temp; k = k - h )
{
test[k + h] = test[k];
}
test[k + h] = temp;
}
}
}while(h > 1);
return;
}
void main()
{
int test[TEST_ARRAY_LEN] = {2,5,1,6,7,3,4,10,9,20,8};
shell_sort(test, TEST_ARRAY_LEN);
for (int i =0; i < TEST_ARRAY_LEN; i++)
{
cout << test[i] << " ";
}
cout << endl;
}
python 实现:
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
step 为希尔排序分的组序号, h为增量
insert_sort 为封装的按步长走的直接插入排序函数
'''
def insert_sort(list, n, h, step):
for i in range(step + h, n, h):
temp = list[i]
for j in range(i, -1, -h):
if list[j - h] > temp:
list[j] = list[j - h]
else:
break
list[j] = temp
return
def shell_sort(list, n):
if (n > len(list)):
return
h = n / 2
while h > 0:
for i in range(0, h):
#对每一组进行直接插入排序
insert_sort(list, n , h, i)
h = h / 2
return list
a = [2,5,1,6,7,3,4,10,9,20,8]
print shell_sort(a,len(a))