经典(Java版)排序算法的分析及实现之二希尔排(2)

/**
    * 从第一个步长数据开始,依次对每个元素与自己组内的数据进行直接插入排序
    * @param sortList
    */
    static void shellSort2(Integer[] sortList) {
        int j, step;
        int len = sortList.length;
        for (step = len / 2; step > 0; step /= 2)
            for (j = step; j < len; j++)
                /**
                * 从数组第step个元素开始,然后将每个元素与自己组内的数据进行直接插入排序
                */
                if (sortList[j] < sortList[j - step]) {
                    int temp = sortList[j];
                    int k = j - step;
                    while (k >= 0 && sortList[k] > temp) {
                        sortList[k + step] = sortList[k];
                        k -= step;
                    }
                    sortList[k + step] = temp;
                }
    }

算法复杂度

1、时间复杂度

希尔排序耗时的操作有:比较 + 后移赋值。时间复杂度如下:

1) 最好情况:序列是升序排列,在这种情况下,需要进行的比较操作需(n-1)次。后移赋值操作为0次。即O(n)

2) 最坏情况:O(nlog2n)。

3) 渐进时间复杂度(平均时间复杂度):O(nlog2n)

平均时间复杂度:O(nlog2n),希尔排序在最坏的情况下和平均情况下执行效率相差不是很多, 与此同时快速排序(O(log2n))在最坏的情况下执行的效率会非常差。专家们提倡,几乎任何排序工作在开始时都可以用希尔排序,若在实际使用中证明它不够快,再改成快速排序这样更高级的排序算法。

增量序列的选择

Shell排序的执行时间依赖于增量序列。

1) 最后一个增量必须为1;

2) 应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况。

Shell排序的时间性能优于直接插入排序

1)当文件初态基本有序时直接插入排序所需的比较和移动次数均较少。

2)当n值较小时,n和的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0()差别不大。

3)在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的一趟排序过程也较快。

2、空间复杂度:O(1)

希尔排序是在原输入数组上进行后移赋值操作的(称“就地排序”),所需开辟的辅助空间跟输入数组规模无关,所以空间复杂度为:O(1)

稳定性

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

附件希尔排序下载

------------------------------------------分割线------------------------------------------

免费下载地址在

用户名与密码都是

具体下载目录在 /2014年资料/12月/12日/经典(Java版)排序算法的分析及实现之二希尔排序

下载方法见

------------------------------------------分割线------------------------------------------

归并排序的实现

直接插入排序的三种实现

直接选择排序及交换二个数据的正确实现

排序总结之选择式排序 

算法----选择排序(select sort)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d8b8e36f9bf07708de2544f763bc3a52.html