排序笔记_______3(Shell排序)

import java.util.Random;

/***
 * Shell排序:(以升序为例)
 * 
 * (几个典型的部分有序数组:
 * 
 * 一、数组中每个元素距离它的最终位置都不远
 * 
 * 二、一个有序的大数组接一个小数组
 * 
 * 三、数组中只有几个元素的位置不正确。)
 * 
 * 思想:
 * 
 * 【使数组中任意间隔为h的元素都是有序的,这样的数组被称为h有序数组。】
 * 
 * 实现方法:
 * 
 * 【1、将h个子数组独立的排序。
 * 
 * 2、(更简单)将每一个h-子数组中的元素移到比他大的元素之前,
 * 
 * 只需要在插入排序的代码中将移动元素的距离有1改为h即可。
 * 
 * 这样,Shell排序的实现就转化成了一个类似于插入排序但使用不同增量的过程。】
 * 
 * 适用的数组:
 * 
 * 【小数组,也可以适用于大数组,对任意排序数组的表现也很好。】
 * 
 * 个人理解:
 * 
 * 【Shell排序是插入排序的改进,插入排序最适用于部分有序数组,
 * 
 * 而Shell排序就是事先将数组变成了部分有序数组,最后在来一趟插入排序,
 * 
 * 从而使数组整体有序。】
 * 
 * 书中解释:
 * 
 * 【Shell排序高校的原因是他权衡了子数组的规模和有序性。
 * 
 * 排序之初,各个子数组都很短,排序后子数组都是部分有序的,这两种情况都很适合插入排序。
 * 
 * 子数组的部分有序取决于递增序列的选择。】
 * 
 * @author LuodiJack
 * 
 */
public class Shell {
    @SuppressWarnings("rawtypes")
    public static void sort(Comparable[] a) {
        int N = a.length;
        int h = 1;
        while (h < N / 3) {// 递增序列(可以事先将其存储在数组中)
            h = h * 3 + 1;// 目前没有最优的递增序列,只能凭借经验,这个递增序列可以适用大部分的实际问题.
        }
        while (h >= 1) {
            for (int i = h; i < N; i++) {// 将a[i]插入到a[i-h],a[i-2*h],a[i-3*h],a[i-4*h],a[i-5*h]......中(和插入排序一样)
                for (int j = i; j >= h && Template.less(a[j], a[j - h]); j -= h) {
                    Template.exch(a, j, j - h);
                }
            }
            h /= 3;
        }
    }

    public static String toString(Integer[] a) {
        String str = "";
        for (int i = 0; i < a.length; i++) {
            str += a[i] + " ";
        }
        return str;
    }

    public static void show(Integer[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Random random = new Random();
        final int MAX = 1000000;
        Integer[] a = new Integer[MAX];
        Integer[] b = new Integer[MAX];

        for (int i = 0; i < MAX; i++) {
            b[i] = a[i] = random.nextInt(MAX);
        }

        ShowTime st1 = new ShowTime();
        sort(a);
        st1.showTime();

        ShowTime st2 = new ShowTime();
        Insertion.sort(b);
        st2.showTime();

        if (toString(a).equals(toString(b))) {
            System.out.println("yes");
        } else {
            System.out.println("no");
            show(a);
            show(b);
        }
    }
}

文中用到的less()、exch()方法,详见类模板。(排序算法笔记____1)
http://blog.csdn.net/a199581/article/details/50651401

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值