希尔排序是在插入排序的基础之上做的优化。那什么是希尔排序呢?
我们知道,再插入排序的时候,如果这个数组基本是有序的,那么数组间数值的移动就会少很多,那么相应的效率就会提高。
希尔的规则是将已有的数组分成几个长度比较小的数组,因为再长度比较小的数组里,数组基本是有序的。
但是有一个缺点就是希尔排序是不稳定的。
我们看一下如何具体的来做希尔排序,源码已经上传到我的GitHub
(1)按照给定的步长来确定我的分组,比如步长为5,那么第一组就是下标为 0 5 10 … 这些数组成,第二组就是 1 6 11 … 等
(2)将分好的组分别做插入排序
(3)将步长适当减小(最后一次的步长必须是1),重复步骤 1 2。
大致的过程就是这个了,下面贴代码
public class ShellSort {
/**
* 交换数据里面的两数
* @param list 需要交换数据的列表
* @param m 交换的数据之一
* @param n 另一个需要交换的数
*/
public static void swap(int[] list , int m , int n) {
int temp = list[n];
list[n] = list[m];
list[m] = temp;
}
/**
* 根据相应步长来做一次插入排序
* @param list 需要排序的数组
* @param t 步长
*/
public static void shellsort(int[] list , int t) {
System.out.println("t = " + t );
for(int i = 0 ; i < t ; i++ ) {
for(int j = i ; j < list.length ; j += t) {
int p = j;
for( int m = j ; m >=0 ; m -= t ) {
if( list[m] > list[p] ) {
swap(list,m,p);
p = m ;
}
}
}
System.out.println(Arrays.toString(list));
}
}
public static void main(String[] args) {
int[] test = {23,44,2,3,11,46,38,5,9,88,5,22};
System.out.println(Arrays.toString(test));
int t = test.length ;
do {
if( 1 != t ) {
t /= 2;
}
shellsort(test, t);
} while( t > 1 ) ;
if( 1 != t ) {
shellsort(test,1);
}
}
}