• 算法


    要点:利用了插入排序对于数据有序性的依赖,先对部分元素位置进行调整,再执行插入排序。整体上降低了插入排序的时间复杂度,是插入排序的改进版本。当然,人品好的,还是用插入吧。

      1 import java.util.Random;
      2 
      3 public class ShellSort<T extends Comparable> {
      4 
      5     public void sort(T[] arr) {
      6         // 数据间距
      7         int space = arr.length / 2;
      8         while (space >= 1) {
      9             // 当前元素下标
     10             int index = 0;
     11             // 每组首元素的下标
     12             int move = 0;
     13             // 按照间距能分出的数据组数
     14             double capcity = Math.floor(arr.length / Math.floor(arr.length / space));
     15             printArr(arr);
     16             while (move < capcity) {
     17                 // 下一个元素下标
     18                 int next = index + space;
     19                 // 对比交换
     20                 if (arr[index].compareTo(arr[next]) > 0) {
     21                     printIndex(index, next);
     22                     T temp = arr[next];
     23                     arr[next] = arr[index];
     24                     arr[index] = temp;
     25                 }
     26                 // 当前坐标移动
     27                 index = next;
     28                 // 一组元素执行完进入下一组,首元素后移一位,当前坐标移至首元素位置
     29                 if (index + space >= arr.length) {
     30                     index = ++move;
     31                 }
     32             }
     33             // 当拆分的组数只有1组时,执行插入排序
     34             if (capcity == 1) {
     35                 for (int i = 1; i < arr.length; i++) {
     36                     if (arr[i].compareTo(arr[i - 1]) < 0) {
     37                         printArr(arr);
     38                         T temp = arr[i];
     39                         for (int j = i; j > 0; j--) {
     40                             arr[j] = arr[j - 1];
     41                             if (arr[j - 1].compareTo(temp) <= 0) {
     42                                 arr[j] = temp;
     43                                 break;
     44                             }
     45                         }
     46                         printArr(arr);
     47                     }
     48                 }
     49             }
     50             // 间距减半
     51             space /= 2;
     52         }
     53     }
     54 
     55     private void printIndex(int index, int next) {
     56         String[] stringArr = new String[]{"|", "|", "|", "|", "|", "|", "|", "|", "|", "|", "|"};
     57         stringArr[index] = "*";
     58         stringArr[next] = "*";
     59         for (String s : stringArr) {
     60             System.out.print(s);
     61         }
     62         System.out.println();
     63     }
     64 
     65     private void printArr(T[] arr) {
     66         for (T n : arr) {
     67             System.out.print(n);
     68         }
     69         System.out.println();
     70     }
     71 
     72     public static void main(String[] args) {
     73         int n = 11;
     74         Integer[] arr = new Integer[n];
     75         for (int i = 0; i < n; i++) {
     76             arr[i] = new Random().nextInt(10);
     77         }
     78         ShellSort ss = new ShellSort();
     79         ss.sort(arr);
     80     }
     81 
     82     /**
     83      * 60372574404 => 原始数据, 按照间隔``arr.length/2``拆分
     84      * *||||*||||| => 交换
     85      * |||||*||||* => 交换 => 发生了顺序改变,因此不稳定
     86      * |||*||||*|| => 交换
     87      * ||||*||||*| => 交换
     88      * 50340474726 => 间隔减半,由5变2
     89      * *|*|||||||| => 交换
     90      * ||*|*|||||| => 交换
     91      * ||||||||*|* => 交换
     92      * |||||||*|*| => 交换
     93      * 30045472647 => 间隔减半,由2变1
     94      * **||||||||| => 交换
     95      * |**|||||||| => 交换
     96      * ||||**||||| => 交换
     97      * ||||||**||| => 交换
     98      * |||||||**|| => 交换
     99      * ||||||||**| => 交换
    100      * 00344526477 => 开始执行插入排序,发现2
    101      *       ^
    102      * 00234456477 => 将2插入到有序位置
    103      * 00234456477 => 发现4
    104      *         ^
    105      * 00234445677 => 将4插入到有序位置
    106      *
    107      * 序列按排序方向的有序性越高,插入排序越快
    108      * 希尔排序是尽可能先排好序,再执行插入,是插入排序的改进版
    109      * 插入拼人品,希尔求稳定
    110      * => 遍历次数:与数据分布有关
    111      * => 时间复杂度:最小为O(nlogn)
    112      * => 稳定性:不稳定
    113      */
    114 
    115 }
  • 相关阅读:
    人月神话阅读笔记03(完)
    人月神话阅读笔记02
    各种前端好用的在线工具、学习网站、插件
    垂直居中css
    输入框判断表情的输入js
    jq九宫格抽奖
    移动端中一像素的解决方案
    获取url地址栏中的参数数据
    ios中getTime()的兼容性问题
    清除Css中select的下拉箭头样式
  • 原文地址:https://www.cnblogs.com/SamNicole1809/p/12800562.html
Copyright © 2020-2023  润新知