插入排序----希尔排序算法

本文详细介绍了希尔排序算法,一种改进的插入排序方法。希尔排序通过将序列分割成子序列并使用特定增量进行排序来提高效率。文章解释了希尔排序的过程、稳定性和时间复杂度,并提供了C++实现代码。

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

希尔排序又称缩小增量排序法。首先,将待排序的关键字序列分成若干个较小的子序列,对子序列进行直接插入排序,使整个待排序序列排好序。

希尔排序是基于插入排序的以下两点性质而提出改进方法的:
1、插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。
2、插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位。

希尔排序的过程:
在希尔排序中,各子序列的排序过程是相对独立的,具体实现时,并不是对一个子序列进行完全排序,再对另一个子序列进行排序。
希尔排序从第一个子序列的第二个元素开始,顺序扫描待排序记录序列,对首先出现的各子序列的第二个元素,分别在各子序列中进行插入处理;然后对随后出现的各自序列的第三个元素,分别在各子序列中进行插入处理,直到处理完各子序列的最后一个元素。

增量的取法:一般采用d = [d/3] + 1

逆转数:在它之前比此关键字大的关键字的个数
逆转数之和就是排序过程中插入某一个待排序记录所需要移动记录的次数。
逆转数为0则表明整个排序完成。

稳定性:
由于多次插入排序,我们知道一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱,所以shell排序是不稳定的

本质上讲,希尔排序算法是直接插入排序算法的一种改进,减少了其复制的次数,速度要快很多。 原因是,当n值很大时数据项每一趟排序需要的个数很少,但数据项的距离很长。当n值减小时每一趟需要和动的数据增多,此时已经接近于它们排序后的最终位置。 正是这两种情况的结合才使希尔排序效率比插入排序高很多。

Shell算法的性能与所选取的分组长度序列有很大关系。

时间复杂度:
一般认为希尔排序的时间复杂度为O(n^1.5),比直接插入法要好。
希尔排序对于中等规模(n<=1000)的序列具有较高的效率。

这里写图片描述



#include <iostream>
using namespace std;

//对记录数组r做一趟希尔排序,length为数组的长度,delta为增量
void ShellInsert(int *r,int length,int delta)
{
    int j;
    //1 + delta为第一个子序列的第二个元素的下标
    for(int i = delta + 1;i <= length;i++)
    {
        if(r[i] < r[i - delta])
        {
            r[0] = r[i];            //备份r[i],不做监视哨 
            for(j = i-delta; j>0&&r[0]<r[j]; j -= delta)
            {
                r[j + delta] = r[j];    
            }
            r[j + delta] = r[0];
        }
    }
}

//对记录数组r做希尔排序,length为数组r的长度
//delta为增量数组,n为delta[]的长度 
void ShellSort(int *r,int length,int *delta,int n)
{
    for(int i = 0;i <= n-1;i++)
    {
        ShellInsert(r,length,delta[i]);
    }
}

int main()
{
    int a[] = {0,48,62,35,77,55,14,18};
    int delta[]={2,1};

    ShellSort(a,7,delta,2); 
    for(int i = 1;i <= 7;i++)
        cout << a[i] << " ";
}
### 希尔排序算法详解 #### 算法概述 希尔排序(Shell Sort),亦称为递减增量排序算法,是对插入排序的一种优化版本[^1]。该算法由Donald Shell于1959年提出,并在论文“A high-speed sorting procedure”中对其进行了详细的阐述[^3]。 #### 工作原理 希尔排序通过比较相隔一定间隔的元素来工作,这些间隔逐渐减少直到变为1。当间隔为1时,希尔排序即成为普通的插入排序。这种策略使得远距离的数据可以更快地移动到接近其最终位置的地方,从而提高了整体性能[^4]。 #### 时间复杂度分析 尽管具体的渐近时间复杂度取决于所使用的间隔序列,但在最坏情况下,希尔排序的时间复杂度通常优于简单的插入排序。对于某些特定的选择间隔序列,平均情况下的表现甚至能够达到接近\( O(n \log n) \)。 #### 实现细节 以下是使用Python编写的希尔排序的具体实现: ```python def shell_sort(arr): n = len(arr) gap = n // 2 while gap > 0: for i in range(gap, n): temp = arr[i] j = i while j >= gap and arr[j - gap] > temp: arr[j] = arr[j - gap] j -= gap arr[j] = temp gap //= 2 if __name__ == "__main__": test_array = [64, 34, 25, 12, 22, 11, 90] print("原始数组:", test_array) shell_sort(test_array) print("排序后的数组:", test_array) ``` 这段代码展示了如何利用逐步缩小的间隔来进行多次部分有序化的操作,最后完成整个列表的完全排序过程[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值