1. 程式人生 > >小橙書閱讀指南(四)——希爾排序及改進算法

小橙書閱讀指南(四)——希爾排序及改進算法

多次 image 影響 mage sys src class emp href

算法描述:希爾排序是一種基於插入排序的快速排序算法,相比於傳統的相鄰插入,希爾排序更加適合大規模亂序數組的排序。和插入算法一樣,我們也可以優化插入和移動的過程從而進一步提升算法效率。

算法圖示:

技術分享圖片

希爾排序算法的實質是首先將一個大的亂序數組變成幾個小的有序數組,再逐步調整數組長度。最後一步依然是做一次傳統意義上的插入排序,只不過經過之前的調整以後,需要移動的元素不會離當前距離太遠。

以下是希爾排序算法的動態示意圖:

技術分享圖片

Java代碼示例:

package algorithms.sorting;

import algorithms.common.Arrays;
import algorithms.common.ArraysGenerator;
import algorithms.Sortable; import java.io.IOException; /** * Created by learnhow on 2018/8/13. */ public class Shell extends Arrays<Integer> implements Sortable<Integer> { @Override public void sort(Integer[] array) { int h = 1; while (h < array.length / 3) { h
= 3 * h + 1; } while (h >= 1) { for (int i = h; i < array.length; ++i) { for (int j = i; j >= h; j -= h) { if (array[j] < array[j - h]) { exchange(array, j, j - h); } } } h
= h / 3; } } public static void main(String arg[]) throws IOException { Integer[] arr = ArraysGenerator.generateDesc(1000, 5000); Shell shell = new Shell(); shell.sort(arr); System.out.println(java.util.Arrays.toString(arr)); System.out.println(ArraysGenerator.isSort(arr, "asc")); } }

Qt/C++代碼示例:

void Shell::sort(int * arr, int len)
{
    int h = 1;
    while (h < len / 3) {
        h = 3 * h + 1;
    }

    while (h >= 1) {
        for (int i = h; i < len; ++i) {
            for (int j = i; j >= h; j -= h) {
                if (arr[j] < arr[j - h]) {
                    int tmp = arr[j];
                    arr[j] = arr[j - h];
                    arr[j - h] = tmp;
                }
            }
        }
        h = h / 3;
    }
}

算法改進:實際上傳統的插入排序和希爾排序影響性能的主要問題是為了達到排序的目的,一個元素可能需要經過多次交換(每次交換動作都需要3次賦值操作)。因此改進的關鍵是如何減少元素交換或減少賦值操作。當然這會增加算法的難度。

Java代碼示例:

package algorithms.sorting;

import algorithms.Sortable;
import algorithms.common.ArraysGenerator;

import java.util.Arrays;

/**
 * Created by learnhow on 2018/8/16.
 */
public class ShellTR implements Sortable<Integer> {
    @Override
    public void sort(Integer[] array) {
        int h = 1;
        while (h < array.length / 3) {
            h = 3 * h + 1;
        }
        while (h > 0) {
            for (int i = h; i < array.length; i++) {
                int temp = array[i];
                int j = i;
                while (j >= h && array[j - h] > temp) {
                    array[j] = array[j - h];
                    j -= h;
                }
                array[j] = temp;
            }
            h = h / 3;
        }
    }

    public static void main(String[] args) {
        Integer[] arr = ArraysGenerator.generateDesc(100, 100);
        ShellTR shellTR = new ShellTR();
        shellTR.sort(arr);
        System.out.println(Arrays.toString(arr));
        System.out.println(ArraysGenerator.isSort(arr, "asc"));

    }
}

Qt/C++代碼示例(略)

相關鏈接:

Algorithms for Java

Algorithms for Qt

小橙書閱讀指南(四)——希爾排序及改進算法