希尔排序

希尔排序是一种改进的插入排序算法,通过设置增量gap将序列分组,对每组使用插入排序,逐步减小gap直到为1,最终完成排序。由于每次排序减少逆序对,提升了效率。该算法在保持插入排序稳定性的基础上,提高了排序速度,但本身是不稳定的排序方法。代码示例展示了希尔排序的分组和插入过程。
摘要由CSDN通过智能技术生成

希尔排序

希尔排序是插入排序经过改进的一个更高效版本,希尔排序是根据序列下标按照一定步长作为增量进行分组, 对每组使用插入排序算法,通过不断降低步长,每组包含的数据逐渐增多,当步长为 1 时,整个序列被分为一组,算法终止。

实例:

序列: 6, 9, 2, 5, 0, 1, 7, 3, 8
取 增量 gap = length/2,gap/=2, gap > 0

数组长度是 9
所以 开始 运算时 gap = 4
在这里插入图片描述
上图中
绿色标记的为一组,要排序的数据
红色标记的是 一组中排序过程中调换位置的数据

gap /= 2 , gap = 2 继续下一次插入排序
在这里插入图片描述
希尔排序的高效已经体现出来
第一组数据 0, 2, 6, 7, 8 已经是有序序列了,对齐进行插入排序时间复杂度为 O(N)
第二列虽然还存在乱序,但是大部分数据也已经是有序序列了
因为每次对每组进行排序后,都会将较小的数据移动到更前方,而较大的数据则移动到后方,减少了逆序数据个数。
所以在一定程度上也提高了性能

gap /= 2 , gap = 1 继续下一次插入排序
在这里插入图片描述
gap = 1 执行结束之后,希尔排序执行完毕,数组已经是一个有序的序列了

代码实现如下:

        /// <summary>
        /// 希尔排序
        /// </summary>
        /// <param name="arr"></param>
        private void ShellSort1(int[] arr)
        {
            for (int gap = arr.Length / 2; gap > 0; gap /= 2)
            {
                InsertSort(arr, gap);
            }
        }

        /// <summary>
        /// 插入排序一个乱序的数组
        /// 下面部分是插入排序的一个衍变
        /// 将 gap 赋值 为 1 就是一个标准的插入排序
        /// </summary>
        /// <param name="arr"></param>
        private void InsertSort(int[] arr, int gap)
        {
            for (int i = gap; i < arr.Length; ++i)
            {
                Insert(arr, i, gap);
            }
        }

        /// <summary>
        /// arr 前 i - 1 个数据,每隔 gap 个位置是已经排序的序列,将第 i 个数排序到正确位置
        /// 每隔 gap 个位置是已经排序的序列,解释如下
        /// 0,0 + gap, 0 + 2 * gap, ... , 0 + N * gap  这些位置的数是已排好序的数列  且 0 + N * gap   < i
        /// 1,1 + gap, 1 + 2 * gap, ... , 1 + N * gap  这些位置的数是已排好序的数列  且 1 + N * gap   < i
        /// m, m + gap, m + 2 * gap, ... , m + N * gap  这些位置的数是已排好序的数列  且 (m < gap) && (m + N * gap < i)
        /// </summary>
        /// <param name="arr"></param>
        /// <param name="i"></param>
        private void Insert(int[] arr, int i, int gap)
        {
            int j = i;
            int temp = arr[j];
            while ((j - gap) >= 0 && temp < arr[j - gap])
            {
                arr[j] = arr[j - gap];
                j -= gap;
            }
            arr[j] = temp;
        }

稳定性:虽然插入排序是稳定的,但是希尔排序在每次分组后会将不同组中的数据进行前后顺序的替换,无法保证原有数据的先后次序,所有希尔排序是不稳定的。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值