排序算法专题-希尔排序

  希尔排序也叫递减增量排序,是第一批冲破O(n2)的算法之一,他的算法思想很简单,首先拟定一个增量gap,一般是从len(nums)//3或者len(nums)//2开始,然后对序列nums[i,i+gap,i+gap*k…]进行插入排序,一轮迭代完成后gap=gap//2,知道gap=1时,排序完成。

  • 算法步骤是:
  • 1:选择一个增量序列 t1,t2,……,tk,其中 ti > tj, tk = 1;:2:按增量序列个数 k,对序列进行 k 趟排序;
  • 2:每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序
  • 举个栗子:
    排序算法专题-希尔排序_第1张图片
  • 图片来源:图解排序算法(二)之希尔排序
  • 代码如下:
import math
def shellSort(nums):
    n = len(nums)
    gap = n//2
    while gap > 0:
        for i in range(gap, n):
            temp = nums[i]
            j = i - gap
            while j >= 0 and nums[j] > temp:
                nums[j+gap] = nums[j]
                j -= gap
            nums[j+gap] = temp
        gap = math.floor(gap//2)

nums = [3,38, 5, 44, 15, 36]
shellSort(nums)
print(nums)
  • 算法解析:希尔排序是在原数组进行操作,此外只有一个gap的新增常量,因此希尔排序的空间复杂度是O(1)。希尔排序的具体时间复杂度不是很好计算,只能拆成两个循环,分别分析是属于哪种类型的复杂度,首先观察第一层循环,迭代公式是 gap = math.floor(gap//2),很明显这是一个O(log n)的时间复杂度,再观察第二层循环,迭代公式是for i in range(gap, n),很明显是一个O(n)的复杂度,最后观察第三层循环,迭代公式是j -= gap,而gap = math.floor(gap//2)因此可以视为一个O(log n)的复杂度,这也是希尔跑排序最坏的时间复杂度O(nlog2 n)。
  • 该算法在进行过程中有可能改变相等元素的相对位置,因此是一种不稳定排序算法。
  • 举个例子,如数8 5 5 6 4 gap = 2
  • 第一轮: 5 5 4 6 8 ,可见,索引2对应的5在第一轮和索引为0的8交换了位置,两个5的相对位置发生了变化。

你可能感兴趣的:(深度,排序算法,算法,数据结构,python,希尔排序)