在学习希尔排序之前,首先要学习插入排序,可以将希尔排序看做插入排序的升级版。
首先,随机生成10个数字。
Random rd = new Random();
int[] num = new int[10];
for (int i = 0; i < num.length; i++) {
num[i] = rd.nextInt(100)+1;
}
System.out.println(Arrays.toString(num));
所得如下
我们便以这十个数字,进行对希尔排序思想的说明。
要进行希尔排序,首先我们要对数据进行分组,那么就要先设置增量,一般增量为N/2,即总数据大小的一半。
那么对于这十个数字来说,以下标0开始,0号元素就要与自己下标加增量大小的下标元素为一组,依次后推,结果如下图:
分组之后,每组内进行插入排序,所以排序之后如图所示:
现在,每个分组都是有序的,但是整体无序,此时,将增量/2,即5/2 = 2;
这时,重新对数据进行分组,分组情况如下:
然后对组内继续进行插入排序,排序之后如图:
之后继续将增量/2,即2/2=1;相当于将全部数据当做一组,进行插入排序,这时整体数据相比较于之前已经趋于有序,所以插入排序的效率会非常高。
排序之后如图所示:
其实,希尔排序就是将数据分为多组进行插入排序,将整体数据变得趋于有序,当增量变为1时,对整体进行插入排序,这时的排序只需进行少量的数据移动,性能是比较不错的。
以下是希尔排序的代码实现:
public class testSort {
public static void main(String[] args) {
Random rd = new Random();
int[] num = new int[10];
for (int i = 0; i < num.length; i++) {
num[i] = rd.nextInt(100)+1;
}
System.out.println(Arrays.toString(num));
shellSort(num);
System.out.println(Arrays.toString(num));
}
/**
* 希尔排序 - 多路的插入排序 - 先将数据进行分组,然后插入排序,
* 使得整个序列局部趋于有序,那么整体也会趋于有序,效率会变高
* @param num
*/
public static void shellSort(int[] num){
int n = num.length;
int temp;
//数据分组,设置增量gap为数据量的一半,然后按一半进行缩减
for (int gap = n/2; gap > 0 ; gap /= 2) {
for (int i = gap; i < n; i++) {
for(int j = i-gap;j >= 0;j = j-gap){
if(num[j+gap] < num[j]){
temp = num[j+gap];
num[j+gap] = num[j];
num[j] = temp;
}else{
break;
}
}
}
}
}
}
运行结果如下: