博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Shell排序(改良的插入排序)
阅读量:5157 次
发布时间:2019-06-13

本文共 2092 字,大约阅读时间需要 6 分钟。

Shell排序算法最初是由D.L Shell于1959年提出,假设要排序的元素有n个,则每个进行插入排序是并不是所偶的元素同时进行,而是去一段间隔。

Shell首先将间隔设定为n/2,然后跳跃的进行插入排序,再来将间隔设定为n/4,跳跃进行排序动作,再来设定时间间隔为n/8、n/16,知道间隔为1之后的最后一次排序终止,由于上一次的排序动作都会将固定间隔内的元素排序好,所以当间隔为1之后的最后一次排序终止,由于上一次的排序动作都会将固定间隔内的元素排序好,所以当间隔越来越小时,某些元素位于正确位置的几率越高,因此最后几次的排序动作将可以大幅减低。

举个例子来说,假如有一未排序的数字如右:89 12 65 97 61 81 27 2 61 98

数字的总数共有10个,所以第一次我们将间隔设定为10/2=5,此时我们对间隔为5的数字进行排序,如下所示:

 

 

总结连线的部分表示要一起进行排序的部分,再来将间隔设定为5/2的商,也就是2,则第二次的插入排序对象如下所示:

 

 

再来间隔设定为2/2=1,此时就是单纯的插入排序了,由于大部分的元素都已大致排序过了,所以最后一次的插入排序机会没有什么排序动作了:

 

 

将间隔设定为n/2是D.L Shell最初所提出,在教科书中使用这个间隔比较好说明,然而Shell排序法的关键在于间隔的设定,例如Sedgewick证明选用以下的间隔可以加快Shell排序算法的速度:

 

 

其中4*(2j)2 + 3*(2j) + 1不可超过元素总数n值,使用上式找出j后代入4*(2j)2 + 3*(2j) + 1求得第一个间隔,然后将2j除以2代入求得第二个间隔,再来依次类推。

 

后来还有人证明有其它的间隔选定方法可以将Shell排序算法的速度再加快;另外Shell排序算法的概念也可以用来改良冒泡排序算法。

 

C#实例:

 

private static void ShellSort()        {            int[] num = new int[] { 70, 80, 31, 37, 10, 11, 48, 60, 33, 80 };            int length = num.Length;            int gap = length / 2;            WriteNumLine(num);             while (gap > 0)            {                for (int k = 0; k < gap; k++)                {                    for (int i = k + gap; i < length; i += gap)                    {                        for (int j = i - gap; j >= k; j -= gap)                        {                            if (num[j] > num[j + gap])                            {                                int temp = num[j + gap];                                num[j + gap] = num[j];                                num[j] = temp;                            }                            else                            {                                break;                            }                        }                    }                }                gap = gap / 2;                 WriteNumLine(num);            }            WriteNumLine(num);        }        private static void WriteNumLine(int[] num)        {            foreach (int i in num)            {                Console.Write(i + " ");            }            Console.WriteLine();        }

 

 

转载于:https://www.cnblogs.com/zxlovenet/p/3536145.html

你可能感兴趣的文章
淡定,啊。数据唯一性
查看>>
深入理解 JavaScript 事件循环(一)— event loop
查看>>
Hive(7)-基本查询语句
查看>>
注意java的对象引用
查看>>
C++ 面向对象 类成员函数this指针
查看>>
NSPredicate的使用,超级强大
查看>>
自动分割mp3等音频视频文件的脚本
查看>>
判断字符串是否为空的注意事项
查看>>
布兰诗歌
查看>>
js编码
查看>>
Pycharm Error loading package list:Status: 403错误解决方法
查看>>
steps/train_sat.sh
查看>>
转:Linux设备树(Device Tree)机制
查看>>
iOS 组件化
查看>>
(转)Tomcat 8 安装和配置、优化
查看>>
(转)Linxu磁盘体系知识介绍及磁盘介绍
查看>>
tkinter布局
查看>>
命令ord
查看>>
Sharepoint 2013搜索服务配置总结(实战)
查看>>
博客盈利请先考虑这七点
查看>>