一、简要
shell排序是选择排序的一种优化
数组 int[]{6,4,3,5,12,1,2,8,7,11,9,10}
1、第一次取步长为index = 12/2 = 6;(间隔数为步长减一)
2、根据步长则可以划分出序列{6,2}、{4,8}、{3,7}、{5,11}、{12,9}、{1,10}
3、分别对各个序列用选择排序法进行排序{2,4,3,5,9,1,6,8,7,11,12,10}
4、第二次取步长为index = 6/2 = 3;
5、根据步长则可以划分出序列{2,5,6,11}、{4,9,8,12}、{3,1,7,10}
6、分别对各个序列用选择排序法进行排序
7、依次类推,直到步长为1时,对整个数据进行排序即可
二、例子如下
package com.and.sort;
import org.junit.Test;
/**
* shell排序(希尔排序)
* @author liangwd
* 1、 先按照步长来确定序列(这里选择a方法)
* a、最初是按照n/2来选择并且对步长取半直到1
* b、kunth序列:步长等于k = k*3 + 1; k从1开始 (1,4,10...)
* c、hibbard序列:步长等于k = 2的k次方-1 (1,3,7,....)
* 2、然后对各个序列进行选择排序
* 3、当步长为1时,则只有一个序列即原始数组,进行选择排序
*/
public class ShellSort {
public void sort(int[] arr){
int index = 0;
int temp = 0;
int j = 0;
int i = 0;
for (index = arr.length/2; index >=1 ; index=index/2) {
// 1、根据步长划分数组为各个序列(实际数组的元素是没有任何变化,只是通过下标表示某些数据在同一序列中)
for (i = index; i < arr.length; i++) {
temp = arr[i];
j = i-index;
// 2、对各个序列进行选择排序,(区别各个序列由步长index可以区分)
while (j>=0 && arr[j] > temp) {
arr[j+index] = arr[j];
j= j - index;
}
arr[j+index] = temp;
}
}
}
public void print(int[] arr){
for(int i=0; i<arr.length; i++){
System.out.print(arr[i] + " ");
}
}
@Test
public void test(){
// 如下数组
// 1、第一次取步长为index = 12/2 = 6;(间隔数为步长减一)
// 2、根据步长则可以划分出序列{6,2}、{4,8}、{3,7}、{5,11}、{12,9}、{1,10}
// 3、分别对各个序列用选择排序法进行排序{2,4,3,5,9,1,6,8,7,11,12,10}
// 4、第二次取步长为index = 6/2 = 3;
// 5、根据步长则可以划分出序列{2,5,6,11}、{4,9,8,12}、{3,1,7,10}
// 6、分别对各个序列用选择排序法进行排序
// 7、依次类推,直到步长为1时,对整个数据进行排序即可
int[] arr = new int[]{6,4,3,5,12,1,2,8,7,11,9,10};
sort(arr);
print(arr);
}
}