一 :希尔排序概括:
/*
摘自维基百科:
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
但插入排序一般来说是低效的,因为插入排序每次只能将数据移动一位
*/
二:算法实现:
/*
摘自维基百科:
希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。
这样可以让一个元素可以一次性地朝最终位置前进一大步。
然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,
但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
*/
1.原数组:数组a[10] ={10,9,8,7,6,5,4,3,2,1}
2.按照n/2步长:即分为5组。
/*
第一次分组(一列一组):
10 9 8 7 6
5 4 3 2 1
结果:(10,5) (9,4) (8,3) (7,2) (6,1) 五组
*/
3.对分组进行直接插入排序
/*
第一次排序:
5 4 3 2 1
10 9 8 7 6
结果:5,4,3,2,1,10,9,8,7,6
*/
4.按照n/2步长,即分为2组。
/*
第二次分组;
5 4
3 2
1 10
9 8
7 6
结果:(5,3,1,9,7) (4,2,10,8,6)两组
*/
5.对这两组进行直接插入排序
/*
第二次排序
1 2
3 4
5 6
7 8
9 10
结果:1,2,3,4,5,6,7,8,9,10
*/
6.按照步长n/2, 即1
普通的插入排序,结果就出来了。
因为我这里的数组有点特殊,看不到变化。
四:代码
package test;
import java.util.Arrays;
/**
* 希尔排序:数组a[n],长度是n+1;
* 步骤:
* 1.在直接插入排序的基础上,按照步长对数组元素分组;
* 2.对同一个分组内的数组进行直接插入排序
* 3.减小步长,按照步长重新分组,之后再次进行插入排序,直到步长为1
* 4.最后一次进行直接插入排序,排序工作完成。
* @author root
*
*/
public class ShelllSort {
static void shellSort( int a[] ){
int n = a.length;
int i , j ,temp,gap ; //gap 是步长
// 步长选择n/2递减,直到步长为1;当gap是1时,就是单次的直接插入排序了
//最外层循环,简单的说就是按照步长分组的次数
for(gap = n/2 ;gap >0 ;gap/=2){
//这层循环其实就是直接插入排序的外层循环;
//按照步长分为n/2个分组,对这几个分组进行直接插入排序
for(i=gap;i<n;i++){
temp=a[i];
for(j=i-gap;j>=0&&temp<a[j];j-=gap){ //注意:这里的j>=0 ;不然会遗漏a[0];
a[j+gap] =a[j];
}
a[j+gap] = temp;
}
}
}
public static void main(String[] args) {
int[] a ={ 10,9,8,7,6,5,4,3,2,1};
shellSort(a);
System.out.println(Arrays.toString(a));
}
}
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
参考:http://blog.youkuaiyun.com/morewindows/article/details/6668714
维基百科:https://zh.wikipedia.org/wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F