数据结构—希尔排序

希尔排序是一种改进的插入排序,通过设置不同的增量 gap 进行多趟排序。文章介绍了希尔排序的基本思想、增量选择策略、算法实现过程,并指出其不稳定性和适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

认识希尔排序


希尔排序也称为缩小增量排序,它的基本思想是:

通过将待排序的元素分为若干个子序列,利用直接插入排序思想对子序列进行排序。然后将该子序列缩小,接着对子序列进行直接插入排序。按照这种思想,直到所有元素都按照关键字有序排列。

增量(gap)的确定方式:

共有3种方法:
1.gap = 需排序的元素个数,每次让 gap /2;
2.取素数,每次让 gap- -,直到 gap =1;
3.gap=需排序的元素个数,每次让 gap /3 +1;
经过大神们的逐一测试,第三种方法效率更高。

具体算法实现:

假设待排序的元素有 n 个,对应的关键字分别为 a1、a2、a3…….an,设 gap =4的元素为同一个子序列,则元素的关键字 a1、a5、….ai、ai+5、an-5 为一个子序列,同理,a2 、a6、….an-6 也为一个子序列,然后对同一个子序列的关键字利用直接插入排序进行排序。第一次排序完,令gap = gap /3 +1,再划分子序列并排序。依此类推,直到 gap =1,此时对整个元素进行排序。

分析图解

这里写图片描述

代码实现

void ShellSort(int array[], int size)
{
    int i = 1;
    int tmp = 0;
    int gap = size;
    while (gap>1)
    {
        gap = gap / 3 + 1;
        for (i = gap; i < size; ++i)
        {
            int key = array[i];
            int end = i - gap;
            while (end >= 0 && key < array[end])
            {
                array[end + gap] = array[end];
                end -= gap;
            }
            array[end + gap] = key;
        }
    }
}

总结

  • 希尔排序是不稳定的。举个例子:假设现有序列为 2  5  4  9  3  6  8  0  1  0,取 gap=4,那么在第一次排序后,最后的 0 会走到  倒数第二个 0 的前面。
  • gap 的确定方法不同,算法的时间复杂度不同,但空间复杂度都是 O(1)。
  • 希尔排序适用于数据量大,且无序的场景,因为在排序的过程中,使用的是直接插入排序的思想,所以也可以将希尔排序看成是直接插入排序的优化。
### C++ 中希尔排序的实现 #### 1. 希尔排序简介 希尔排序是一种基于插入排序的改进版本,通过比较相隔一定间隔的元素来减少数据移动次数。随着间隔逐渐减小,最终变为1时完成完全有序化过程[^4]。 #### 2. 数据结构选择 对于希尔排序而言,在C++中最常用的数据结构就是数组。因为该算法主要依赖于索引操作来进行元素交换和比较,而数组提供了随机访问特性,非常适合此类需求。 #### 3. 实现细节说明 以下是完整的C++代码示例: ```cpp #include <iostream> using namespace std; void shellSort(int arr[], int n) { // 初始增量gap为数组长度的一半,并逐步缩小至1 for (int gap = n / 2; gap > 0; gap /= 2) { // 对每个子序列执行直接插入排序 for (int i = gap; i < n; ++i) { int temp = arr[i]; int j; // 将arr[i]插入到已排序部分中的适当位置 for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) { arr[j] = arr[j - gap]; } arr[j] = temp; } } } // 打印数组函数 void printArray(const int* arr, size_t size) { for (size_t i = 0; i != size; ++i) cout << arr[i] << " "; cout << endl; } ``` 此段程序定义了一个`shellSort()`函数用于对整型数组进行升序排列。其中采用了动态调整步长的方式,即从较大的间隔开始直到最后变成普通的插入排序。每次迭代都会使当前待处理区间内的所有元素更加接近其最终应处的位置,从而提高了整体效率[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值