Java希尔排序
原理:
希尔排序是插入排序的改进版本。希尔排序将数组数据进行分组。
如何分组?首先,确定一个增长量h,基于增长量对数据进行分组。
例如,当增长量h = 3时,数组中下标为0、3、6、9… 的元素为一组,下标为1、4、7、10… 的元素为一组,依此类推。然后对每一组都进行插入排序。这样就算是完成了一趟排序,之后对增长量h进行减少(规则是 h = h/2 ),然后继续基于当前的增长量h进行分组,分完组继续进行插入排序。
重复以上的操作直到增长量小于1就停止,排序完成。
最开始的增长量h如何确定?规则如下:
int h = 1;
while (h < len/2){//len为待排序数组长度
h = h*2+1;
}
//循环结束后就得到初始增长量h
举例:对数组 { 4、2、6、3、1、8、7、10、9、5 } 进行希尔排序
图示:
代码实现:
package com.example.algorithmdemo.sortingAlgorithm;
/**
* 希尔排序
*/
public class Shell {
public static void sort(Comparable[] a){
int len = a.length;
//确定初始增长量
//循环结束得到增长量
int h = 1;
while (h < len/2){
h = h*2+1;
}
//开始排序
//增长量小于1,排序结束
while (h >= 1){
//找到待排序的值
for(int i = h;i < len;i++){
//分组插入排序
for(int j = i;j >= h;j -= h){
if(greater(a[j-h],a[j])){
//若前一个大于后一个则交换
exchange(a,j-h,j);
}else{
//找到合适位置,结束循环,开始下一个待排序的值的排序
break;
}
}
}
//减少增长量
h = h/2;
}
}
/**
* 判断参数a是否比参数b大
* 返回true/false
* @param a
* @param b
* @return
*/
private static boolean greater(Comparable a,Comparable b){
return a.compareTo(b)>0;
}
/**
* 数组元素i和j交换位置
* @param a
* @param i
* @param j
*/
private static void exchange(Comparable[] a,int i,int j){
Comparable temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
package com.example.algorithmdemo.test;
import com.example.algorithmdemo.sortingAlgorithm.Shell;
import java.util.Arrays;
public class ShellTest {
public static void main(String[] args) {
Integer[] a = {4,2,6,3,1,8,7,10,9,5};//4、2、6、3、1、8、7、10、9、5
Shell.sort(a);
System.out.println(Arrays.toString(a));
}
}
运行结果:
提示:在处理大批量数据时,希尔排序的性能高于插入排序