Ghero 2020-04-17
希尔排序的思想:将序列看成一个矩阵,根据一个步长序列将原序列分成m个列,逐列进行排序,直到列数变为1列为止
因此希尔排序的时间复杂度与步长关系密切。
希尔本人给出的步长序列为: n / (2^k),其中n为序列元素的个数,k >= 1,取整数
举例: 序列元素有32个,那步长序列为 [1, 2, 4, 8, 16],在进行希尔算法时,按步长从大到时小,先分成16列,再8列....最后分成一列,即完成排序
class ShellSort { var array = [5, 7, 2, 8, 9, 4, 7, 3, 2] var shellSteps: [Int] init() { shellSteps = Array<Int>() shellSteps = shellStep() } // 获取希尔步长序列 func shellStep() -> [Int] { var steps = [Int]() var count = array.count >> 1 while count > 0 { steps.append(count) count = (count >> 1) } return steps } func sort() { for step in shellSteps { sort(step: step) } } func sort(step: Int) { for col in 0 ..< step { for begin in stride(from: col + step, to: array.count, by: step) { var current = begin while current > col, array[current] < array[current - step] { let tmp = array[current] array[current] = array[current - step] array[current - step] = tmp current -= step } } } } }
* 最好时间复杂度为: O(n),希尔步长序列的最坏时间复杂度为:O(n^2)
* 空间复杂度为: O(1)
* 稳定性: 不稳定排序
要知道时间复杂度只是描述一个增长趋势,复杂度为O的排序算法执行时间不一定比复杂度为O长,因为在计算O时省略了系数、常数、低阶。实际上,在对小规模数据进行排序时,n2的值实际比 knlogn+c还要小。