`

排序算法(二)--希尔排序(插入排序)

阅读更多
  希尔排序属于插入排序的一种,也称为缩小增量排序

基本思想:
  将待排序数列划分为几个数列,对这几个数列分别进行直接插入排序

具体操作:
  选取增量d(小于数列长度n),将数列划分为n/d个数列,对划分的数列进行直接插入排序
  再选取一个增量d1,d1<d,重复上述步骤
  直到dn = 1结束
取d=5
23   52   12   63   8   17   28   72   36   41
----------------------------------------------
23                      17 
 |_______________________|
     52                      28
      |_______________________|
          12                      72
           |_______________________|
               63                      36
                |_______________________|
                    8                       41
                    |_______________________|
一趟排序结果:
17   28   12   36   8   23   52   72   63   41
----------------------------------------------
取d=2
17        12        8        52        63      
 |_________|________|_________|_________|
     28        36       23        72        41
      |________|_________|________|_________|
二趟排序结果:
8    23   12   28   17   36   52   41   63   72
---------------------------------------------
取d=1
三趟排序结果:
8    12   17   23   28   36   41   52   63   72   
        



时间复杂度:
  很难判断准确的时间复杂度,这和选择的增量d有关系
  最坏情况和平均情况一样:O(n*log(n))

稳定性:
  一次插入排序是稳定的,但是希尔排序是多次插入,在不同的插入排序过程中,相同元素在各自的插入排序中位置可能会变更,所以是不稳定排序

python代码示例:shell_sort.py
def shell_sort(l):
    length = len(l)
    d = length/2         #起始增量d选取为数列的一半
    while(d >= 1):
        for i in range(d, length):  #对l[d...n-1]分别插入各组有序子序列中
            j = i - d
            while(j >= 0 and l[j] > l[j+d]):  #距离增量d的两个元素比较  
                tmp = l[j]
                l[j] = l[j+d]
                l[j+d] = tmp
                j -= d             #以d为增量,继续循环比较该子序列内的元素
        d = d/2              #下一增量选取

if __name__ == '__main__':
    l = [93,102,36,82,76,84,55,63,49,27]
    shell_sort(l)
    print('result:' + str(l)


lua代码示例:shell_sort.lua
require "math"
function shell_sort(t)
    length = table.getn(t)
    d = math:floor(lenght/2)
    while(d >= 1) do
        for i = d+1, length do      --对t[d...n-1]分别插入各组有序子序列中
            j = i - d
            while(j > 0 and t[j] > t[j+d]) do
                tmp = t[j]
                t[j] = t[j+d]
                t[j+d] = tmp
                j = j - d
            end
        end
        d = math:floor(d/2)
    end
end

t = {93,102,36,82,76,84,55,63,49,27}
shell_sort(t)
for _, v in ipairs(t) do
   print v
end

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics