排序算法之希尔排序

排序算法之希尔排序

背景

希尔排序是对插入排序的优化,如果一个长度为N的数组中,数值最小的元素恰好在数组最末端,则将该元素归位(假设从小到大插入排序)得移动N-1次。

特点

相对于插入排序是移动相邻元素,希尔排序移动的是不相邻的元素,先对数组的局部进行排序,最终借助插入排序将局部有序的数组排序

中心思想

使数组中任意间隔为h的元素都是有序的

操作步骤

  • 先找出待排序数组的h序列,可通过h = h * 3 + 1; h < N得到(h=1,4,7…;h最小是1)
  • 对每个h插入排序,得到一个h有序数组(h有序数组必须是一个由h个有序子数组构成的数组,每个子数组中的元素都是由原数组中间隔为h的元素组成)

举例

有一N=16的无序数组,h=4时如下图:
这里写图片描述
得到了4个子数组后,一种方式是分别对4个子数组进行插入排序,但此种方式可能需要3个循环(外循环来选择子数组,两个内循环来对该子数组进行插入排序)。一种简单的做法是将每个元素都和它之前相距h的元素进行插入排序(该例中可从i=4元素开始插入排序),即比较的轨迹不再沿着子数组。从M开始,M和L插入排序,H和E插入排序,L和E插入排序,E和A插入排序,P和M和L插入排序…最终R和L、E、A插入排序

代码实现

public void sort(int[] a) {
    int N = a.length;
    int h = 1;
    while(h * 3 + 1 < N){
        h = h * 3 + 1;
    }//得到h序列中最大值
    while(h > 0){
        //对i之前所有间隔为h的元素进行插入排序
        for(int i = h; i < N; i++){
            for(int j = i; j > h; j = j - h){
                if (a[j-h] > a[j]) {
                    swap(a, j-h, j);
                }
            }
        }
        h = (h - 1) / 3;//换下一个h
    }
}

private void swap(int[] a, int m, int n){
    int temp = a[m];
    a[m] = a[n];
    a[n] = a[m];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值