排序算法--希尔排序(Java)

排序算法–希尔排序

一、学习资料:

简书–八大排序算法

博客–八大排序算法

视频–韩老师java讲解希尔排序

一、希尔排序法介绍

希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。

二、希尔排序法基本思想

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止

三、示例图:

在这里插入图片描述

四、代码
4.1、 希尔排序一(分组冒泡)
/**
     * 希尔排序
     * 根据步长的分组冒泡排序
     * 
     * 100000个随机数花费时间(三次测试):34941ms  30509ms  31519ms
     * 平均时间:32323ms
     * @param arr
     */
    public static void shellSort1(int[] arr) {
        //遍历步长,每遍历一轮步长除2,直到小于等于0跳出循环
        for (int d = arr.length/2;d>0;d/=2){
            //遍历每个元素
            for (int i = d;i<arr.length;i++){
                //遍历本步长组中的元素
                for (int j=i-d;j>=0;j-=d ){
                    //将当前元素与加上步长的元素比对
                    //如果当前元素大就交换位置
                    if (arr[j]>arr[j+d]){
                        //交换位置
                        int temp = arr[j];
                        arr[j] = arr[j+d];
                        arr[j+d] = temp;
                    }
                }
            }
        }
    }
4.2、希尔排序二(分组插入优化)
    /**
     * 希尔排序优化
     * 根据步长的分组插入排序
     * 此方法加入了同组插入优化,不需要每次都是同组冒泡排序
     * 100000个随机数花费时间(三次测试):31ms  40ms  35ms
     * 平均时间:35ms
     * @num
     */
    public static void shellSort2(int[] num){
        //获取num数组的长度
        int length=num.length;
        //遍历步长
        for(int d=length/2;d>0;d/=2){
            //分组比较
            for(int i=d;i<length;i++){
                //获取当前的下标
                int j=i;
                //获取当前值
                int temp=num[j];
                //同组中如果这个数前面还有数并且比这个数小说明还没有找到位置
                //此时将同组中这个数后移步长d位,直到找到要插入的位置
                while(j-d>=0&&temp<num[j-d]){
                    //同组这个数向后移
                    num[j]=num[j-d];
                    //再向前搜索
                    j-=d;
                }
                //循环完后就可以得到插入的位置了(并且要移动了才有插入操作)
                if(j!=i){
                    num[j]=temp;
                }
            }
        }
    }
4.3、测试代码
package com.lxf.sort;

import java.util.Arrays;
import java.util.Random;

public class XiErSort {
    public static void main(String[] args) {
		//测试    	

        //获取一个数字字符串
        StringBuilder stringBuilder = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 100000; i++) {
            stringBuilder.append(random.nextInt(500)+",");
        }
        //去掉最后一个,
        stringBuilder.setLength(stringBuilder.length()-1);
        //获取整数数组
        String[] splits= stringBuilder.toString().split(",");
        int[] nums = Arrays.stream(splits).mapToInt(Integer::valueOf).toArray();
        //获取开始时间
        long  start = System.currentTimeMillis();
        System.out.println("start = " + start);
        //希尔排序
        //shellSort1(nums);
        shellSort2(nums);
        //获取执行完的时间
        long end = System.currentTimeMillis();
        System.out.println("end = " + end);
        //计算执行时间
        long sub=end-start;
        System.out.println("花费时间="+sub);
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值