package com.athangzhou.springcloud.service.impl;
import com.alibaba.fastjson.JSON;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 希尔排序 8万条数据,希尔算法
* 位移法 用时1秒 性能高
* 交换法 用时6秒 性能低
*/
public class ShellSort {
public static void main(String[] args) {
int arr[] = {0, 9, 2, 4, 5, 6, 8, 1, 3, 7};
int[] testArr = new int[80000];
for (int i = 1; i < 80000; i++) {
testArr[i] = (int) (Math.random() * 80000);
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = simpleDateFormat.format(new Date());
System.out.println("希尔算法:移位法计算开始时间" + format);
shellSort(testArr);
String formatEnd = simpleDateFormat.format(new Date());
System.out.println("希尔算法:位移法 计算结束时间" + formatEnd);
System.out.println("");
System.out.println("");
System.out.println("");
System.out.println("");
String exchangeSortStart = simpleDateFormat.format(new Date());
System.out.println("希尔算法:交换法计算开始时间" + exchangeSortStart);
exchangeSort(testArr);
String exchangeSortEnd = simpleDateFormat.format(new Date());
System.out.println("希尔算法:交换法计算结束时间" + exchangeSortEnd);
}
//希尔排序算法 移位法
public static void shellSort(int[] arr) {
int count = 0;
//分组思想
for (int group = arr.length / 2; group > 0; group /= 2) {
//第二步 分为2组 即5/2=2 {0,1,5,9,4},{8,3,6,2,7} 最后结果:{0,2,1,3,4,6,5,7,9,8}
//从第group个元素依次对其所在的组进行直接插入排序
for (int i = group; i < arr.length; i++) {
//要插入数的索引 0
int j = i;
//要插入数的值 arr[5]=6
//{0,9,2,4,5,6,8,1,3,7}
//{0,6},{9,8},{2,1},{4,3},{5,7}
//{0,9,2,4,5,6,8,1,3,7}
int insertValue = arr[j];
//比较 arr[5]与arr[0]的值 如果小于 则移位插入
//步长
if (arr[j] < arr[j - group]) {
while (j - group >= 0 && insertValue < arr[j - group]) {
arr[j] = arr[j - group];
j -= group;
}
}
//退出while循环说明temp找到了位置
arr[j] = insertValue;
}
// System.out.println("第" + (++count) + "次插入结果: " + JSON.toJSONString(arr));
}
// System.out.println("JSON.toJSONString(arr) = " + JSON.toJSONString(arr));
}
/**
* 希尔排序交换算法 从小到大排序
* <p>
* 如果从大到小排序,>改为<即可
*
* @param arr arr
*/
public static void exchangeSort(int arr[]) {
int temp = 0;
int count = 0;
for (int group = arr.length / 2; group > 0; group /= 2) {
//因为第一次分为了5组,所以从索引下标=5开始
for (int i = group; i < arr.length; i++) {
//只遍历两次 从0开始
for (int j = i - group; j >= 0; j -= group) {
if (arr[j] > arr[j + group]) {
temp = arr[j];
arr[j] = arr[j + group];
arr[j + group] = temp;
}
}
}
// System.out.println("第" + (++count) + "次排序结果:" + JSON.toJSONString(arr));
}
/* int groupTest = arr.length / 2;
while (groupTest > 0) {
//因为第一次分为了5组,所以从索引下标=5开始
for (int i = groupTest; i < arr.length; i++) {
//只遍历两次 从0开始
for (int j = i - groupTest; j >= 0; j -= groupTest) {
if (arr[j] > arr[j + groupTest]) {
temp = arr[j];
arr[j] = arr[j + groupTest];
arr[j + groupTest] = temp;
}
}
}
System.out.println("第" + groupTest + "次排序结果:" + JSON.toJSONString(arr));
groupTest = groupTest / 2;
}*/
}
/**
* 希尔排序思路:
* {0,9,2,4,5,6,8,1,3,7}
* <p>
* 第一步: 分为5组 即length/2 10/2=5 {0,6},{9,8},{2,1},{4,3},{5,7} 各自比较大小 小数放前面,大数放后面替换位置
* 最后结果: {0,8,1,3,5,6,9,2,4,7}
* <p>
* 第二步 分为2组 即5/2=2 {0,1,5,9,4},{8,3,6,2,7}
* 最后结果:{0,2,1,3,4,6,5,7,9,8}
* <p>
* 第三步: 分为1组 即2/2 {0,2,1,3,4,6,5,7,9,8}
* 最后结果:{0,1,2,3,4,5,6,7,8,9}
*/
public static void test(int arr[]) {
int temp = 0;
//因为第一次分为了5组,所以从索引下标=5开始
for (int i = 5; i < arr.length; i++) {
//只遍历两次 从0开始
for (int j = i - 5; j >= 0; j -= 5) {
if (arr[j] < arr[j + 5]) {
temp = arr[j];
arr[j] = arr[j + 5];
arr[j + 5] = temp;
}
}
}
System.out.println("第一次排序结果:" + JSON.toJSONString(arr));
//因为第二次分为了5/2=2组,所以从索引下标=2开始 [0,8,1,3,5,6,9,2,4,7]
//第二步 分为2组 即5/2=2 {0,1,5,9,4},{8,3,6,2,7}
// 最后结果:{0,2,1,3,4,6,5,7,9,8}
for (int i = 2; i < arr.length; i++) {
//只遍历两次 从0开始
for (int j = i - 2; j >= 0; j -= 2) {
if (arr[j + 2] < arr[j]) {
temp = arr[j];
arr[j] = arr[j + 2];
arr[j + 2] = temp;
}
}
}
System.out.println("第二次排序结果:" + JSON.toJSONString(arr));
//因为第二次分为了5/2=2组,所以从索引下标=2开始 [0,8,1,3,5,6,9,2,4,7]
//第二步 分为2组 即5/2=2 {0,1,5,9,4},{8,3,6,2,7}
// 最后结果:{0,2,1,3,4,6,5,7,9,8}
for (int i = 1; i < arr.length; i++) {
//只遍历两次 从0开始
for (int j = i - 1; j >= 0; j -= 1) {
if (arr[j + 1] < arr[j]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("第三次排序结果:" + JSON.toJSONString(arr));
}
}
打印结果:
希尔算法:移位法计算开始时间2020-04-22 23:56:24
希尔算法:位移法 计算结束时间2020-04-22 23:56:24
希尔算法:交换法计算开始时间2020-04-22 23:56:24
希尔算法:交换法计算结束时间2020-04-22 23:56:30