简体   繁体   中英

3 Way Quicksort algorithms

This is the 3-way quicksort...

private void quicksort3(int[] input, int low, int high)
{
    int i = low - 1, j = high, left = low - 1, right = high, pivot = input[high], k;

    if (high <= low) return;
    while (true)
    {
        while (input[++i] < pivot) ;
        while (pivot < input[--j])
            if (j == low) break;
        if (i >= j) break;
        swap(input, i, j);
        if (input[i] == pivot) 
        {
            left++; 
            swap(input, left, i); 
        }
        if (pivot == input[j]) {
            right--;
            swap(input, j, right);
        }
    }
    swap(input, i, high); j = i - 1; i++;
    for (k = low; k < left; k++, j--) 
        swap(input, k, j);
    for (k = high - 1; k > right; k--, i++) 
        swap(input, i, k);
    quicksort3(input, low, j);
    quicksort3(input, i, high);
}

For input 9 5 3 I get exception error Index was outside the bounds of the array. the exception occurs here pivot = input[high] where the value of high is -1 (so I understand why I have error) but how I can fix it?

I call function like that quicksort3(arr,0,arr.Length-1);

but how I can fix it?

By bailing out earlier when this edge condition is reached.

 //int i = low - 1, j = high, left = low - 1, right = high, pivot = input[high], k;
 //if (high <= low) return;

 if (high <= low) return;
 int i = low - 1, j = high, left = low - 1, right = high, pivot = input[high], k;

Your value assignment is executed before the boundary condition is checked. So you should put pivot = input[high] after line if (high <= low) return; .

May be a little offtopic, but there's great 3 way quicksort in Robert Sedgewick and Kevin Wayne book "Algorithms" , I just love this code, it's so simple and it does exact what it intended to do.
You can see it here - Quick3way.java

private static void sort(Comparable[] a, int lo, int hi) { 
    if (hi <= lo) return;
    int lt = lo, gt = hi;
    Comparable v = a[lo];
    int i = lo;
    while (i <= gt) {
        int cmp = a[i].compareTo(v);
        if      (cmp < 0) exch(a, lt++, i++);
        else if (cmp > 0) exch(a, i, gt--);
        else              i++;
    }

    sort(a, lo, lt-1);
    sort(a, gt+1, hi);
}

This should work:

 while(a[i++]<v); 
 while(a[j]>v) 
   j--; 

The rest is ok.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM