Shell排序 Python C#

希尔排序是计算机科学家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()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值