6-4希尔排序

交换式希尔排序


基本思想

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰
被分成一组,算法便终止

图解

1621072578016

1621073015461

代码实现

分步推导

        //希尔第一轮排序
        //将10和数据分为五组	
        for (int i = 5; i < a.length; i++) {
            //遍历各组的元素  步长为5
            for (int j=i-5;j>=0;j-=5){
                //如果前边元素大于后边 则交换
                if (a[j]>a[j+5]){
                    int temp = a[j];
                    a[j] = a[j+5];
                    a[j+5] = temp;
                }
            }
        }

完整

package sort;

/**
 * @Function :
 * date 2021/5/15 - 18:02
 * How :
 */
public class ShellSort {
    public static void main(String[] args) {
        int[] a = {8,9,0,7,5,3,2,6,4,1};
        ShellSort shellSort = new ShellSort();
        shellSort.sort(a);
    }
    public void sort(int[] array){

        int temp;
        //假如 10 个数据 初始增量和步为5
        // 增量每次都/2
        //代表有几次希尔
        for (int k = array.length / 2; k > 0; k /= 2) {

            //希尔 第 K 轮排序  已经将初始分为了lengh/2组数据
            // 遍历各组数据
            // 各组 后一个数据
            for (int i = k; i < array.length; i++) {
                //后一个数据 - 步长 = 前一个数据
                for (int j = i; j >= k; j -= k) {
                    //交换
                    if (array[j - k] > array[j]) {
                        temp = array[j - k];
                        array[j - k] = array[j];
                        array[j] = temp;
                    }
                }
            }
        }
        Util.print(array);
    }
}

在使用希尔排序时,需要选择合适的增量序列作为排序辅助,而这也是一个比较复杂的抉择。所以希尔排序在实际使用排序时并不常用。
但是作为一个优化排序的思想,我们还是应该好好学习它。

移位式希尔排序


基本思想

改进式希尔排序速度快

利用直接插入排序结合希尔排序

代码实现

package sort;

/**
 * @Function :
 * date 2021/5/15 - 19:11
 * How :
 */
public class ShellSortShift {
    public static void main(String[] args) {
        int[] a = {8,18,9,12,0,7,5,3,2,6,4,1,11};
        sort(a);
    }
    public static void sort(int[] array){

        int temp;
        //假如 10 个数据 初始增量和步为5
        // 增量每次都/2
        //代表有几次希尔
        for (int step = array.length / 2; step > 0; step /= 2) {
            //从第step开始对其组元素进行直接插入排序
            for (int i = step; i < array.length; i++) {
                int index = i;   //要插入位置的下标
                int insertNode = array[index];   //要插入的元素
                if (array[index]<array[index-step]){
                    while (index-step>=0 && insertNode<array[index-step]){
                        //移位
                        array[index] = array[index-step];
                        index-=step;
                    }
                    array[index] = insertNode;
                }
            }
        }

        Util.print(array);
    }
}

posted @ 2021-11-23 21:12  剪水行舟  阅读(46)  评论(0)    收藏  举报