希尔排序
前言:在博客写这些文章的目的用于记录所学,怕以后忘了,如果哪里写的不对欢迎指正,谢谢!!
学习目标:掌握希尔排序算法的原理和思想
一、前提知识
排序算法概念、时间复杂度。可前往此网址 排序算法学习01_算法基础介绍阅读
需要了解直接插入排序
二、希尔排序介绍
希尔排序(Shellsort),也称递减增量排序算法,是直接插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
三、希尔排序工作原理
其实就比直接插入排序多一点,就是分组。
上面讲过,希尔排序也称递减增量排序算法,这个增量,其实就是分组中各个元素的距离。递减:每次缩小元素之间的距离。
通过每次缩小分组来执行直接插入排序,经过多次对多个分组排序后,即可得到最终结果。
四、希尔排序算法设计思想
首先讨论两点:1.如何分组 2.如何缩小分组
假设选择有这样一条数列{3,2,5,1,7,9,8},要做递增效果:
,这个看作为最原始的分组
那我们第一次分组时,该分组增量跨度必须够大,这样可保证如果后面存在小的值,可以提前过来。所以,第一次增量值为: Increment = a.length/2,增量为3的构成一组,那么将被分为3组
[3,1,8],[2,7],[5,9],分别对这三个组进行直接插入排序,排序之后元素1就会到前面去了,变成这样
然后再次缩小增量,除以2,Increment = Increment / 2,现在为增量为1的构成一组,进行直接插入排序
这里就用文字说了:1 和 2 比较,不用换,2和5不用,5和3比较,只移动一次
1 2 3 5 7 9 8
5和7不用,7和9不用,9和8比较,只移动一次
1 2 3 5 7 8 9
当分组到增量为1时,数列只需要简单微调,最后的结果即可出来
现在我们又回到开头,1.怎么分组,用数组长度除以2 2.怎么缩小分组,再次除以2
分组和元素变化过程:首次时,组最多,但是此时每个组包含元素最少。慢慢缩小增量,组变少,每个组包含元素变多
排序时:挑选分组中的值来排序
五、根据以上思路设计希尔排序算法
要求对以下这个数列进行递增排序:{3,2,5,1,7,9,8}
package com.migu.sortingAlgorithm;
import java.util.Arrays;
/**
* 希尔排序
*/
public class ShellSort {
public static void main(String[] args) {
int a[] = {3,2,5,1,7,9,8};
// 根据前面所讲的增量,来设置循环
for(int increment = a.length / 2;increment >= 1; increment/=2){
// 以下结构跟我们上篇所讲的直接插入排序很像
// 1.从分组后序列的第二位开始走
for(int i = increment+increment;i < a.length;i++){
int insertVal = a[i]; // 保存待插入元素
int insertIndex= i-increment; // 插入所在索引,从待插入元素的前一位开始判断,也是从后往前走
while (insertIndex >= 0 && a[insertIndex] > insertVal){
a[insertIndex+increment] = a[insertIndex];
insertIndex-=increment;
}
a[insertIndex+increment] = insertVal; // 执行插入,while循环结束后,还会减掉增量,所以要加上去
}
}
System.out.println(Arrays.toString(a)); // 调用工具类输出
}
}
还有一种方法:是跟冒泡排序结合使用,我称他为希尔式冒泡排序,在for循环里放置如下代码
// 根据前面所讲的增量,来设置循环
for(int increment = a.length / 2;increment >= 1; increment/=2){
// 对全部分组执行冒泡,当增量为1时,就相当于普通冒泡排序,但这个冒泡排序此时已经不怎么需要冒了
for(int i = increment;i < a.length;i++){
int j = i;
// 从后往前开始冒泡
while (j-increment >=0 && a[j] < a[j - increment]) {
int temp = a[j];
a[j] = a[j - increment];
a[j - increment] = temp;
j-=increment;
}
}
}
我在我笔记本用Date类测了一下,在100万条随机数(0~100万)的数据下,两者运算都在一秒内,差不了多少
六、时间复杂度
网上所说该算法最坏情况为O(n),但是我就觉得该玩意很快,前面说过了,分别对希尔排序两种方式的算法使用100万条数据进行排序,时间都在1秒之内,可能因为硬件的问题,但我这台电脑配置真的很低
七、总结
希尔排序算法通过把原本大的数列划分成一个个组来进行排序,最后再进行总体排序时,经过简单微调即可排序完毕,只能说太牛了