1. import java.util.Arrays;
    2. import org.junit.Test;
    3. /**
    4. * 希尔排序
    5. * 插入排序的一种
    6. */
    7. public class HeerSort {
    8. //希尔排序,它包括了交换法和移动法两种方式
    9. public int[] heerSort(int[] arrays){
    10. if(null == arrays){
    11. throw new NullPointerException("arrays is null");
    12. }
    13. if(!(arrays.length>0)){
    14. return arrays;
    15. }
    16. int[] sortArrays = Arrays.copyOf(arrays, arrays.length);
    17. // sort(sortArrays);
    18. sortOpt(sortArrays);
    19. return sortArrays;
    20. }
    21. //移动法
    22. private int[] sort(int[] sortArrays){
    23. int length = sortArrays.length;
    24. // 先求出最大区间值
    25. int rCtl = 1;
    26. while(rCtl*2+2<length){
    27. rCtl = rCtl*2+2;
    28. }
    29. // 循环---将区间值减半
    30. while (rCtl>0){
    31. // 从第rCtl位开始,按区间进行插入排序
    32. for(int i = rCtl;i<rCtl*2;i++){
    33. // [1,*,*,*,3,*,*,*,2,*,*,*,7,*,*,*,5,*,*,*]
    34. for(int j = i;j<length;j+=rCtl){
    35. // 找到插入的位置
    36. int insertnum = j;
    37. int temp = sortArrays[j];
    38. for(int c = j-rCtl;c>=0;c-=rCtl){
    39. // 将在j前面的值,如果大于j,就往后挪一位
    40. if(sortArrays[c]>temp){
    41. sortArrays[c+rCtl] = sortArrays[c];
    42. insertnum = c;
    43. }else{
    44. break;
    45. }
    46. }
    47. sortArrays[insertnum] = temp;
    48. }
    49. }
    50. rCtl=rCtl/2;
    51. }
    52. return sortArrays;
    53. }
    54. //代码优化写法
    55. // 最外部不需要跨区间去循环,将外部跨区间循环与区间内部循环合成一个循环
    56. // 因为本质还是从 0+fctl的位置一直遍历到最后一个
    57. private void sortOpt(int[] arrays){
    58. int len = arrays.length;
    59. //定义区间大小
    60. int fctl = 1;
    61. //计算出最大区间
    62. while(2*fctl+2<len){
    63. fctl = 2*fctl+2;
    64. }
    65. while(fctl>0){
    66. for(int i = fctl;i<len;i++){
    67. int sortValue = arrays[i];
    68. int insertKey = i;
    69. //找到待排序的值所在的分组中该插入的位置
    70. while((insertKey-fctl)>=0&&sortValue<arrays[insertKey-fctl]){
    71. arrays[insertKey] = arrays[insertKey-fctl];
    72. insertKey-=fctl;
    73. }
    74. arrays[insertKey] = sortValue;
    75. }
    76. fctl = fctl/2;
    77. }
    78. }
    79. @Test
    80. public void test(){
    81. int [] arr1 = new int[]{9,3,5,7,2,8,4,1,6,2};
    82. System.out.println(Arrays.toString(heerSort(arr1)));
    83. }
    84. }