Domanda

Sto cercando di capire il 3-way Quicksort digitale, e io non capisco perché la variabile cutoff lì? e il metodo di inserimento?

public class Quick3string {

    private static final int CUTOFF =  15;   // cutoff to insertion sort

    // sort the array a[] of strings
    public static void sort(String[] a) {
        // StdRandom.shuffle(a);
        sort(a, 0, a.length-1, 0);
        assert isSorted(a);
    }

    // return the dth character of s, -1 if d = length of s
    private static int charAt(String s, int d) { 
        assert d >= 0 && d <= s.length();
        if (d == s.length()) return -1;
        return s.charAt(d);
    }


    // 3-way string quicksort a[lo..hi] starting at dth character
    private static void sort(String[] a, int lo, int hi, int d) { 

        // cutoff to insertion sort for small subarrays
        if (hi <= lo + CUTOFF) {
            insertion(a, lo, hi, d);
            return;
        }

        int lt = lo, gt = hi;
        int v = charAt(a[lo], d);
        int i = lo + 1;
        while (i <= gt) {
            int t = charAt(a[i], d);
            if      (t < v) exch(a, lt++, i++);
            else if (t > v) exch(a, i, gt--);
            else              i++;
        }

        // a[lo..lt-1] < v = a[lt..gt] < a[gt+1..hi]. 
        sort(a, lo, lt-1, d);
        if (v >= 0) sort(a, lt, gt, d+1);
        sort(a, gt+1, hi, d);
    }

    // sort from a[lo] to a[hi], starting at the dth character
    private static void insertion(String[] a, int lo, int hi, int d) {
        for (int i = lo; i <= hi; i++)
            for (int j = i; j > lo && less(a[j], a[j-1], d); j--)
                exch(a, j, j-1);
    }

    // exchange a[i] and a[j]
    private static void exch(String[] a, int i, int j) {
        String temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    // is v less than w, starting at character d
    private static boolean less(String v, String w, int d) {
        assert v.substring(0, d).equals(w.substring(0, d));
        return v.substring(d).compareTo(w.substring(d)) < 0; 
    }


    // is the array sorted
    private static boolean isSorted(String[] a) {
        for (int i = 1; i < a.length; i++)
            if (a[i].compareTo(a[i-1]) < 0) return false;
        return true;
    }


    public static void main(String[] args) {

        // read in the strings from standard input
        String[] a = StdIn.readAll().split("\\s+");
        int N = a.length;

        // sort the strings
        sort(a);

        // print the results
        for (int i = 0; i < N; i++)
            StdOut.println(a[i]);
    }
}

http://www.cs.princeton.edu/ algs4 / 51radix / Quick3string.java.html

È stato utile?

Soluzione

Sembrerebbe essere utilizzati al fine di inserzione invoke ordinamento per sufficientemente piccolo (dimensioni <= 15) array. Questo è più probabile per accelerare l'ordinamento.

Altri suggerimenti

Si tratta di una semplice ottimizzazione dell'algoritmo quicksort. Il costo delle chiamate ricorsive in quicksort sono piuttosto alto, quindi per piccoli array per inserzione funziona meglio. Così, l'idea è che, se la lunghezza del sottoarray di essere os ordinato sotto certa soglia, è meglio ordinare utilizzando insertion sort di quicksort. Nel tuo esempio, definisce variabili CUTOFF tale soglia, cioè se è inferiore a 15 elementi sono lasciati, essi vengono ordinati utilizzando inserzione invece di quicksort.

Il metodo sort sopra è un metodo ricorsivo. E ogni metodo ricorsivo dovrebbe avere una sorta di caso base (altrimenti mantenersi chiamare, alla fine portano a un overflow dello stack).

La porzione di inserimento è il caso base a tale metodo, perché ad ogni passo ricorsivo, la differenza hi-lo continua a diminuire, e quando la sua inferiore CUTOFF, l'inserzione sarà eventualmente attivato, costringendo il ricorsione di arresto.

if (hi <= lo + CUTOFF) {       // base case
    insertion(a, lo, hi, d);
    return;
}

Ora, perché l'inserimento? Perché funziona bene per i piccoli array. Altro su di ordinamento qui: http://www.sorting-algorithms.com/

Questa idea nasce da Robert Sedgewick, che sa di più su quello che probabilmente Quicksort qualsiasi uomo vivo. Si è citato in Donald E. Knuth, The Art of Computer Programming, Volume III, dove si dimostra che per le piccole e M, insertion sort è più veloce di Quicksort, così egli raccomanda non smistamento partizioni piccole < M a tutti e lasciando una sorta inserimento definitivo nell'intero insieme di dati alla fine. Knuth dà una funzione di calcolo M (che è il vostro CUTOFF), e che è per il suo 9 MIX pseudo-computer.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top