数据结构与算法 - 希尔排序

希尔排序

希尔排序,它是由 D.L.Shell 于1959 年提出而得名。根据它的名字很难想象算法的核心思想。它的核心思想是把一个序列分组,对分组后的内容进行插入排序,这里的分组只是逻辑上的分组,不会重新开辟存储空间。它其实是插入排序的优化版,插入排序对基本有序的序列性能好,希尔排序利用这一特性把原序列分组,对每个分组进行排序,逐步完成排序。

arr = [ 8, 1, 4, 6, 2, 3, 5, 7 ] 为例,通过 floor(8/2) 来分为 4 组,8 表示数组中元素的个数。分完组后,对组内元素进行插入排序。

image

「 利用第 1 次分组结果进行第 2 次分组 」

image

「 利用第 2 次分组结果进行最后一次分组 」

image

代码实现

#include <iostream>
#include <vector>
#include <priority_queue>

using namespace std;

void shell_sort(vector<int> &nums) {
    int len = nums.size();

    for(int gap = floor(len/2); gap > 0; gap = floor(gap/2)) {
        for(int i = gap; i < len; i++) {
            for(int j = i - gap; j >= 0 && nums[j] > nums[j+gap]; j-=gap) {
                // swap nums[j] and nums[j+gap]
                nums[j] = nums[j] ^ nums[j+gap];
                nums[j+gap] = nums[j] ^ nums[j+gap];
                nums[j] = nums[j] ^ nums[j+gap];
            }
        }
    }
}

特点

稳定性:它可能会把相同元素分到不同的组中,那么两个相同的元素就有可能调换相对位置,故不稳定。

空间复杂度:由于整个排序过程是在原数据上进行操作,故为 \(O(1)\);

时间复杂度:希尔排序的时间复杂度与增量序列的选取有关,例如希尔增量时间复杂度为\()(n^2)\),而Hibbard增量的希尔排序的时间复杂度为 \(\frac{3}{2}O(\log n)\),希尔排序时间复杂度的下界是 \(n*\log n\)

posted @ 2021-12-28 13:59  Logan_Xu  阅读(37)  评论(0编辑  收藏  举报