数据结构-希尔排序

虽然从宏观上看希尔排序是把一堆数分组进行排序,但是从代码实现上来说,本质上还是两个数的两两比较

实现过程

  1. 增量gap是数组长度的一半,且每次循环过后都会将gap再缩小一半
  2. 获得增量gap之后将 i 设置为gap的值
    • 每次的比较实际上都是两个数进行比大小的
    • i 用于记录靠右边数字的索引
    • 每次循环都把 i 的值给 index 变量存着,这样如果一个数需要和前面多个数进行比较的时候可以改变index来修改右边数的索引
  3. j 用于记录左边数字的索引
    • 如果arr[j] > arr[index]的话就将两数换位置,并修改index:index = j;
    • 下一轮如果j -= gap符合条件的话,这时候左边数的索引 j 就已经向左偏移了 gap 位了,而右边数索引index也相应偏移了 gap 位。这样可以做到一个数不停地和间隔gap位的前面的数进行插入排序比较
    • 如果找到了一个左边数比右边数小的话,因为是用来插入排序,所以可以直接break来退出当次循环

代码实现

import java.util.Arrays;

/**
 * @author 小火娃
 * @project_name: my_project
 * @package_name: com.xiaohuowa.shell
 */
public class ShellSort {
    public static void main(String[] args) {
        // int[] arr = new int[]{2,9,4,7,3,3,6,5};
        int[] arr = new int[]{15,5,2,7,12,6,1,4,3,9,8,10};
        System.out.println("排序前数组:\t\t" + Arrays.toString(arr));

        // 临时变量
        int temp = 0;
        //  记录比较次数
        int time = 1;
        int index= 0;
        // 外层gap用于控制增量
        for (int gap = arr.length / 2; gap > 0; gap /= 2) {
            // i用于在一轮排序中拿到靠右边的数字
            for (int i = gap; i < arr.length; i++) {
                // index 用于记录一次比较中右边数字的索引位置
                index = i;
                // j 用于在一轮排序中拿到靠左边的数字的索引
                for (int j = i - gap; j >= 0; j -= gap) {
                    // 如果左边数字比右边大的话就换位
                    if (arr[j] > arr[index]) {
                        temp = arr[j];
                        arr[j] = arr[index];
                        arr[index] = temp;
                        // 换位之后把 j 赋值给右边数字的索引
                        // 这样当循环 j-=gap 的时候,就可以让改变后的右边索引和改变后的左边索引的两数进行比较了
                        index = j;
                    } else {
                        // 因为用的是插入排序,所以左边只要比右边小了,之后的循环就可以停了
                        break;
                    }
                }
            }
            System.out.println("第" + time++ + "趟排序结果:" + Arrays.toString(arr));
        }
        System.out.println("排序完成后数组:\t" + Arrays.toString(arr));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值