0
点赞
收藏
分享

微信扫一扫

希尔排序 +java +数据结构

小沙坨 2022-04-16 阅读 89

希尔排序 Shell Sort

缩小增量排序。
简单插入排序的改进高效版本。
把记录 按 下标的增量 一个一个分组。

相比于插入排序改进点

间隔大的时候,移动次数少。
间隔小的时候,移动距离比较短。

首先给一个间隔
其次缩小间隔
直到间隔为1

图解

在这里插入图片描述

10个数,10/2,分为5组

利用步长 8 和 3一组
9 和 5 一组
以此类推

每组之间交换,8和3交换
5和9交换
1和4不发生交换
7和6交换
2和0交换

目的:尽快让小的数,往前移动

5个数,5/2分为2组
3 1 5 9 7
5 6 8 4 2
这两组,进行调整
0 1 3 7 9
2 4 5 6 8
0214357698

2/2 = 1
013456789
总结组数变化; 5–2—1

题目

有一群小牛,考试成绩分别是 {8,9,1,7,2,3,5,4,6,0}请从小到大排序.请分别使

理解

首先
1)希尔排序时,对有序序列在插入时采用交换法,并测试排序速度。
2)希尔排序时,对有序序列在插入时采用移动法,并测试排序速度。

交换法

package sort;

import java.util.Arrays;

public class ShellSort {
  public static void main(String[] args) {
    //
    int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
    shellSort(arr);
  }

  public static void shellSort(int[] arr) {
    System.out.println("原始数组: " + Arrays.toString(arr));
    // 希尔排序的第1轮排序
    // 第一轮循环,将10个数,分为5组
    for (int i = 5; i < arr.length; i++) {
      // 遍历各组中所有的元素
      // 遍历各组中所有元素(共5组,每组2个),步长为5
      for (int j = i - 5; j >= 0; j -= 5) {
        // 如果当前元素 大于 + 步长后的元素,说明 交换
        if (arr[j] > arr[j + 5]) {
          int temp = arr[j];
          arr[j] = arr[j + 5];
          arr[j + 5] = temp;
        }
      }
    }
    System.out.println("一轮数组: " + Arrays.toString(arr));


    //希尔排序第二轮,将10个数组分为 5/2 = 2 组
    for (int i = 2; i < arr.length; i++) {
      // 遍历各组中所有的元素
      // 遍历各组中所有元素(共5组,每组2个),步长为5
      for (int j = i - 2; j >= 0; j -= 2) {
        // 如果当前元素 大于 + 步长后的元素,说明 交换
        if (arr[j] > arr[j + 2]) {
          int temp = arr[j];
          arr[j] = arr[j + 2];
          arr[j + 2] = temp;
        }
      }
    }
    System.out.println("二轮数组: " + Arrays.toString(arr));


    //希尔排序第三轮,将10个数组分为 2/2 = 1 组
    for (int i = 1; i < arr.length; i++) {
      // 遍历各组中所有的元素
      // 遍历各组中所有元素(共5组,每组2个),步长为5
      for (int j = i - 1; j >= 0; j -= 1) {
        // 如果当前元素 大于 + 步长后的元素,说明 交换
        if (arr[j] > arr[j + 1]) {
          int temp = arr[j];
          arr[j] = arr[j + 1];
          arr[j + 1] = temp;
        }
      }
    }
    System.out.println("三轮数组: " + Arrays.toString(arr));
  }
}

原始数组: [8, 9, 1, 7, 2, 3, 5, 4, 6, 0]
一轮数组: [3, 5, 1, 6, 0, 8, 9, 4, 7, 2]
二轮数组: [0, 2, 1, 4, 3, 5, 7, 6, 9, 8]
二轮数组: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

整理

package sort;

import java.util.Arrays;

public class ShellSort {
  public static void main(String[] args) {
    //
    int[] arr = {8, 9, 1, 7, 2, 3, 5, 4, 6, 0};
    shellSort(arr);
  }

  public static void shellSort(int[] arr) {
    System.out.println("原始数组: " + Arrays.toString(arr));
    int temp = 0;
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
      // 遍历各组中所有元素(共gap组),步长为gap
      for (int i = gap; i < arr.length; i++) {
        for (int j = i - gap; j >= 0; j -= gap) {
          if (arr[j] > arr[j + gap]) {
            temp = arr[j];
            arr[j] = arr[j + gap];
            arr[j + gap] = temp;
          }
        }
      }
      System.out.println(gap);
      System.out.printf("轮数组: " + Arrays.toString(arr) + "\n");
    }

  }
}

or 这么写

  public static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
  }

  public static void shellSort3(int[] arr) {

    for (int gap = arr.length / 2; gap > 0; gap /= 2) {
      for (int i = gap; i < arr.length; i++) {
        for (int j = i; j > gap - 1; j -= gap) {
          if (arr[j] < arr[j - gap]) {
            swap(arr, j, j - gap);
          }
        }
      }
    }
    System.out.println(Arrays.toString(arr));

交换式希尔排序优化—>移位法

平均时间复杂度

在这里插入图片描述

举报

相关推荐

0 条评论