数据结构经典算法之希尔排序

目录

 

希尔排序

一、操作方法

二、排序方法:

三、动图演示

四、C#实现代码

五、性能分析:


希尔排序

希尔排序又称“缩小增量排序”。基本思想:先取一个小于n的整数d1作为第一个增量,然后把文件的全部记录分成d1个组。所有距离为d1的倍数的记录放在同个一个组中,现在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组中的分组和排序,直到所取的增量dt=(dt<dt-1<0<d2<d1),即所有记录放在同一组中进行直接插入排序为止。

实质上希尔排序也是直接插入排序一种,只是它是分组插入的,相比直接插入而言,它的效率更高一点,首先它把较大的数据集合分割成若干个小组(逻辑上分组),然后对每一个小组分别进行插入排序,此时,插入排序所作用的数据量比较小(每一个小组),插入的效率比较高。

希尔排序是记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

一、操作方法

操作流程图:

                            

二、排序方法:

一般取d1=n/2,di+1=di/2。如果结果为偶数,则加1,以保证di为奇数。

如上图所示,目前这组数据有10个数,这是将这组数据分组,根据公式d1=n/2,则第一趟排序为10/2=5,将数据分为5组。这5组数据那两个为一组呢?这时就看他们中间的空,因为第一趟排序d=5组,所以以他们中间的空为准,就是说隔五个空格为一组。

这里所要注意的是如果出现除完之后结果为小数的则向下取整。

例如:5/2=2.5,所以这里应该取2。在分组的时候隔两个空为一组。

三、动图演示

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

相关博客

https://blog.csdn.net/qq_39207948/article/details/80006224


四、C#实现代码

using System;
namespace ConsoleApplication8
{
    //希尔排序类
    class ShellSorter
    {
        public void Sort(int[] list)
        {
      int _d = list.Length;
            int _len = list.Length;
            for (_d = _d / 2; _d > 0; )
            {
                if (_d % 2 == 0) _d++;

                //按d分组

                for (int i = 0; i < _d; i++)

                {

                    //每组执行直接插入排序算法

                    for (int j = i + _d; j < _len; j += _d)

                    {
                        if (j < _len)

                        {
                           if (list[j] < list[j - _d])//后面小于前面

                            {
                                int temp = list[j];

                                int k = 0;

                                for (k = j - _d; k >= i && temp < list[k]; k -= _d)//比它大的元素后移动
                                {
                                    list[k + _d] = list[k];
                                }

                                list[k + _d] = temp;//插入最后比它小的后面

                            }
                        }
                    }
                }

                Console.WriteLine("第一次d->" + _d);

                for (int i = 0; i < _len; i++)

                {
                   Console.Write(string.Format("{0},", list[i]));
                }

                Console.WriteLine("");

                _d = _d / 2;

            }
        }
    }

五、性能分析:

空间效率仅仅使用了常数个辅助单元,空间复杂度为o(1)

时间效率由于其是依赖于增量函数的排序,在某个特定范围内,希尔排序的时间复杂度约为o(n^1.3),最坏情况下时间复杂度为o(n^2)。

稳定性:在划分字表的同时,会造成元素相对位置的变化,因此是不稳定的。

适用性:希尔排序算法仅仅适用于当线性表为顺序存储的情况。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 25
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值