Python 每日一记224>>>Java实现希尔排序算法及双层循环的理解

一、什么是希尔排序

我的理解:希尔排序也叫做递减增量排序,核心是分组的插入排序,h的值就是增量,表示相差h距离的元素为一组,注意,必须是连续的相差这么多才能成为一组,比如h=5时,9和4相差5,但是5不在和除了9以外的数相差5,因为数据不够长,所以只有9和5为一组;当h=2时,4和2相差2,2和5又相差2,5和8又相差2,依次连接连续相差2的元素,就能成为一组。每次h的值都要减半(取整的减半),最后要为1,关于h的最初值没有同意的规定,但是以下算法可以当作一个参考:

int h=1;
        while (h<arr.length/2){
            h=2*h+1;
        }

当分组完成后,就对每一组进行插入排序,以h=2时为例,此时4,2,5,8,5,为一组,对这一组进行插入排序,首先2和4比较,2比4小,2和4互换位置,然后这一组变为2,4,5,8,5,接下来5和4比较,5大于4,位置不变,接着8和5比较,也不变位置,接着5和8比较,交换位置,数组变为2,4,5,5,8,接着5和5比较,位置不变。这一组排序完成,然后进行第二组的插入排序,类似的操作。接着再缩小h,直到h=1,进行最后一次插入排序,即可排序完成。
在这里插入图片描述

二、算法实现

import java.lang.reflect.Array;
import java.util.Arrays;

//实现Comparable接口
class ShellSort {
//比较算法,如果大于零,表示a比b大.
// 注意Comparable接口类型可能让人能疑惑,
// 请记住父类接口指向子类实例,就懂了,类/接口是可以作为类型的
    public static boolean comparing(Comparable a,Comparable b){
        return a.compareTo(b)>0;
    }
//交换算法,要有一个临时变量进行传递
    public static void exchange(Comparable[]arr,int i,int j){
        Comparable temp;
        temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
//排序
    public static void sort(Comparable[]arr){
//参考的h值设定算法,你可以自己设定开始的h值
        int h=1;
        while (h<arr.length/2){
            h=2*h+1;
        }
//        当h>0时
        while (h>0){
//            关于两层循环详见第三部分
//            外层循环,找到待插入的元素
            for (int i=h;i<arr.length;i++){
//                内层循环,把待插入的元素插入到有序序列中
                for(int j=i;j>=h;j-=h){
                    if(comparing(arr[j-h],arr[j])){
                        exchange(arr,j-h,j);
                    }else{
                        break;
                    }
                }

            }
//            每循环一次,h减半,取整,直到1
            h=h/2;
        }
    }
}

public class Test{

    public static void main(String[] args) {
//        定义一个数组
        Integer[]arr={6,5,4,7,1,70,9,0};
        System.out.println("排序前的数组:"+Arrays.toString(arr));
//        调用方法,注意是静态方法,可以这样调用
        ShellSort.sort(arr);
        System.out.println("排序前的数组:"+Arrays.toString(arr));
    }
}

结果:
在这里插入图片描述

三、希尔排序两层循环的理解

在这里插入图片描述

外层循环+内层循环

外层循环寻找待插入元素,虽然我们根据h把数据分为了几组,但是每一组都有一个待插入元素,第一组为索引号以0开始的一组元素,这一组的第一个待插入元素的索引为h,第二组的的第一个待插入元素索引为h+1,以h=2为例,数据被分为了2组,其实元素2及其以后的元素都是待插入元素,虽然这些元素被分为了多组。因此外层循环可以为for (int i=h;i<arr.length;i++),这个循环和h有关,而h也是循环的,每次循环减半取整。
在待插入元素确定之后,内层循环就是解决将待插入元素使用插入排序法排序。这个循环是for(int j=i;j>=h;j-=h),j的初始值为i,最小为h,j的步长为-h,这个步长保证的是对每个每个组的元素进行插入排序。

发布了235 篇原创文章 · 获赞 24 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/weixin_44663675/article/details/105216472