希尔排序(java)

希尔排序是对直接插入排序的一种优化,基本思想是把待排序的数据元素分成若干个小组,对同一小组内的数据元素用直接插入法排序;小组的个数逐次缩小;当完成了所有数据元素都在一个组内的排序后排序过程结束。希尔排序又称作缩小增量排序。

常用的h序列由Knuth提出,该序列从1开始,通过如下公式产生:

h = 3 * h +1

反过来程序需要反向计算h序列,应该使用

h=(h-1)/3

希尔排序的过程

package shellSort;

public class ShellSort {
    public int[] sort(int[] array) {
        // 计算出最大的h值
        int h = 1;
        while (h <= array.length / 3) {
            h = h * 3 + 1;
        }
        while (h > 0) {
            for (int i = h; i < array.length; i += h) {
                if (array[i] < array[i - h]) {
                    int tmp = array[i];
                    int j = i - h;
                    while (j >= 0 && array[j] > tmp) {
                        array[j + h] = array[j];
                        j -= h;
                    }
                    array[j + h] = tmp;

                }
            }
            // 计算出下一个h值
            h = (h - 1) / 3;
        }
        return array;
    }
    
}

测试代码:

package Test;

import bubbleSort.BubbleSort;
import insertSort.InsertSort;
import merge.MergeSort;
import quickSort.QuickSort;
import selectSort.SelectSort;
import shellSort.ShellSort;

public class Test {
    public static void main(String[] args) {

        ShellSort shellSort = new ShellSort();    
        int[] array = createArray();
        long ct1 = System.currentTimeMillis();    
        int[] arrays = shellSort.sort(array);
        long ct2 = System.currentTimeMillis();
        display(arrays);        
        System.out.println("所消耗的时间:" + (ct2 - ct1) + " ms");
        
    }

    public static void display(int[] arrays) {
        System.out.println("排序后数据:");
        for (int i = 0; i < arrays.length; i++) {
            System.out.print(arrays[i] + "	");
            if ((i + 1) % 10 == 0) {
                System.out.println();
            }
        }
        System.out.println();
    }

    public static int[] createArray() {
        int[] array = new int[100000];    
        System.out.println("数组中元素是:");
        for (int i = 0; i < 100000; i++) {
            array[i] = (int) (Math.random() * 1000);
            System.out.print(array[i] + "	");
            if ((i + 1) % 10 == 0) {
                System.out.println();
            }
        }
        
        System.out.println();
        return array;
    }
}

对100000个数的排序时间大约是2200ms, 比插入排序快了大约一倍, 但是还是不高;

时间复杂度是很难分析的。

原文地址:https://www.cnblogs.com/wangnuo/p/7463161.html