博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
希尔排序算法
阅读量:5334 次
发布时间:2019-06-15

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

希尔排序的基本思想

  ①希尔排序又称缩小增量排序 ,它本质上是一个插入排序算法。为什么呢?

  因为,对于插入排序而言,插入排序是将当前待排序的元素与前面所有的元素比较,而希尔排序是将当前元素  与前面增量位置上的元素进行比较,然后,再将该元素插入到合适位置。当一趟希尔排序完成后,处于增量位置上的元素是有序的。

  ②希尔排序算法的效率依赖于增量的选取

  假设增量序列为 h(1),h(2).....h(k),其中h(1)必须为1,且h(1)<h(2)<...h(k) 。

  第一趟排序时在增量为h(k)的各个元素上进行比较;

  第二趟排序在增量为h(k-1)的各个元素上进行比较;

  ..........

  最后一趟在增量h(1)上进行比较。由此可以看出,每进行一趟排序,增量是一个不断减少的过程,因此称之为缩小增量。

希尔排序的效率和适用场景

  希尔排序的执行时间为O(N*(logN)2),比快速排序慢(O(N*logN)),比简单排序快(O(N2))

  希尔排序对于中等规模的数据量的排序是良好的比如1000量级的数据量(亲测1000量级马上排序完成,10000量级等了差不多一分钟)他的特点是在最坏的情况和在平均情况下执行效率基本没有什么差别,而快速排序在最坏的情况下执行效率会非常差,相比较而言,在稳定性上希尔算法更好。

java程序

package sy;class ArraySh{    private long[] theArray;    private int nElems;        public ArraySh(int max)    {        theArray = new long[max];        nElems = 0;    }        public void inset(long value)    {        theArray[nElems] = value;        nElems++;    }        public void display(){        System.out.print("A = ");        for(int j = 0; j < nElems; j++)        {            System.out.print(theArray[j] + " ");        }        System.out.println("");            }    //希尔排序方法    public void shellSort(){        //定义内循环和外循环变量        int outer,inner;        //定义临时变量存储插入项        long temp;        //定义增量并赋值为1        int h = 1;        //寻找h最大的可能值,也是第一轮第一个数组的第二项,也是第一轮第一个数组的插入项,也是希尔排序的第一个插入项        while(h <= nElems / 3)        {            h = h * 3 + 1;        }        //正式开始希尔排序,当h增量为0时停止希尔排序        while(h > 0)        {            //1.这里其实是增量为h的插入排序,原插入排序增量始终为1,效率十分低下。                        //2.在希尔排序的增量h为1的时候,整个数组其实基本有序了,在基本有序的数组使用插入算法相当高效,这时候的插入排序算法比较和复制的操作不超过两次            //3.这层for循环其实在每一轮增量改变后执行,目的是排序小数组,比如增量为3的数组[12,34,45,21,54,23]被分成三个小数组,该循环第一轮执行[12,21]的排序,第二轮执行[34,54]的排序,第三轮执行[45,23]的排序            for(outer = h; outer < nElems; outer++)            {                //将插入项赋值给临时变量                temp = theArray[outer];                //将内外循环连接                inner = outer;                //判断插入项的插入位置  条件是插入项和前面的有序部分比较而且小,并且inner大于0                while(inner > h -1 && theArray[inner - h] >= temp)                {                                        //比插入项大的有序部分全部后移一位                    theArray[inner] = theArray[inner - h];                    inner -= h;                }                //把插入项发在比它大的数据项的位置                theArray[inner] = temp;                        }            //增量h减少            h = (h - 1) / 3;                }    }}class App{    public static void main(String[] args)    {        int maxSize = 10;        ArraySh arr;        arr = new ArraySh(maxSize);                for(int j = 0 ; j < maxSize; j++)        {            long n = (int)(java.lang.Math.random() * 99);            arr.inset(n);        }        arr.display();        arr.shellSort();        arr.display();            }}

 

转载于:https://www.cnblogs.com/iwebkit/p/7613316.html

你可能感兴趣的文章
python的猴子补丁monkey patch
查看>>
架构模式: API网关
查看>>
正则验证积累
查看>>
Linux学习-汇总
查看>>
83. 删除排序链表中的重复元素
查看>>
bzoj1048 [HAOI2007]分割矩阵
查看>>
python中的__init__ 、__new__、__call__等内置函数的剖析
查看>>
Java中的编码
查看>>
PKUWC2018 5/6
查看>>
As-If-Serial 理解
查看>>
MYSQL SHOW VARIABLES简介
查看>>
雷林鹏分享:Redis 简介
查看>>
C# 网页自动填表自动登录 .
查看>>
netfilter 和 iptables
查看>>
洛谷P1005 矩阵取数游戏
查看>>
Django ORM操作
查看>>
在Silverlight中使用HierarchicalDataTemplate为TreeView实现递归树状结构
查看>>
HDU-1150 Machine Schedule 二分图匹配
查看>>
单例模式的5种写法
查看>>
安卓问题报告小记(四):Some projects cannot be imported because they already exist in the workspace...
查看>>