希尔排序是计算机科学家Donald L.Shell而得名。
希尔排序不像快速排序那么快。因为在最坏和最理想的情况下效率差别不算太多,所以稳定性比快速排序好一些。
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
开发人员:Edwin
开发日期:
开发工具:PyCharm
功能描述:写法跟算法描述基本一致容易理解
-------------------------------------------------
"""
def shell_sort(alist: []) -> None:
'''
Shell排序
:param alist:
:return:
'''
# 间隔与子序列数量相同
gap = len(alist) // 2
while gap > 0:
for startposition in range(gap):
gap_insert_sort(alist, startposition, gap)
gap = gap // 2
def gap_insert_sort(alist, start, gap):
'''
以步长 gap 将原始序列划分成 gap 个待排序的序列,对每个序列使用普通的插入排序进行排序
序列1: [alist[0], alist[gap], alist[2*gap]...]
序列2: [alist[1], alist[1+gap], alist[1 + 2*gap]...]
序列3: [alist[2], alist[2+gap], alist[2 + 2*gap]...]
...
序列end: [alist[gap-1], alist[2*gap-1], alist[3*gap-1]...]
"采用插入排序算法从序列的第二个元素开始" 分别是alist[gap], alist[1+gap], alist[2+gap] ...等于start+gap,序列内第一个元素只是比对对象
:param alist: 数组
:param start: 每个序列的开始元素
:param gap: 数列间隔
:return:
'''
for i in range(start + gap, len(alist), gap):
currentvalue = alist[i]
position = i
while position >= gap and alist[position - gap] > currentvalue:
alist[position] = alist[position - gap]
position = position - gap
alist[position] = currentvalue
# print(f"间隙为{gap}后的结果 {alist}")
if __name__ == '__main__':
L1 = [54, 26, 93, 17, 77, 31, 44, 55, 20, 5]
print('Before: ', L1)
shell_sort(L1)
print('After: ', L1)
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
开发人员:Edwin
开发日期:
开发工具:PyCharm
功能描述:gap每递增1,都在抽象化的子序列中切换,完成插入排序。这种写法简练,来自互联网。
-------------------------------------------------
"""
def shell_sort(alist: []) -> None:
gap = len(alist) // 2
while gap > 0:
for i in range(gap, len(alist)):
temp = alist[i]
j = i
while j >= gap and temp < alist[j - gap]:
alist[j] = alist[j - gap]
j -= gap
alist[j] = temp
# print(f"间隙为{gap}后的结果 {alist}")
gap = gap // 2
if __name__ == '__main__':
L1 = [45, 26, 88, 17, 76, 31, 44, 55, 20]
print('Before: ', L1)
shell_sort(L1)
print('After: ', L1)
如下是C#
间隔增量
Knuth间隔序列。
h=h*3+1递归调用可增至最大间隔数。
h=(h-1)/3可以减至起点。
当然还有别的序列方法:例如:h=(5*h-1)/11;
序列方案可以自己制定,但是更多的专家采用非对称互质的方法。但是这样也带来了一些问题,比如需要循环至起点又很麻烦,
反到影响了效能。
如下代码就有这样的难题,这个问题保留至此,以后碰上更好的方案在改。
/// <summary>
/// 希尔排序算法
/// </summary>
/// <param name="lngArr" >传入的数组/param>
public void shellSort(long[] lngArr)
{
int intOut = 0;
int intIn = 0;
int intElems = lngArr.Length;
int intFlam = 0;
while (intFlam <= intElems / 3)
{
intFlam = intFlam * 3 + 1;
}
while (intFlam > 0)
{
for (intOut = intFlam; intOut < intElems; intOut++)
{
long temp = lngArr[intOut];
intIn = intOut;
while (intIn > intFlam - 1 && lngArr[intIn -intFlam] >= temp)
{
lngArr[intIn] = lngArr[intIn -intFlam];
intIn -= intFlam;
}
lngArr[intIn] = temp;
} // end for
intFlam = (intFlam - 1) / 3;
}
}// end shellSort()