Reputation: 121
I have been trying to implement a normal non hybrid quicksort algorithm an d it works for arrays up to about 100 fields in size. I get the exception "stack-overflow" with most of you are probably familiar with. Here is my source code:
import java.util.Arrays;
public class Quicksort {
public int[] zahlenliste;
public Quicksort(int[] zahlenliste) {
sort(zahlenliste);
}
public void sort(int[] zahlenliste) {
if (zahlenliste == null || zahlenliste.length == 0) {
return;
}
this.zahlenliste = zahlenliste;
quickSort(0, zahlenliste.length - 1);
}
public void quickSort(int begin, int end) {
if (begin >= end) {
return;
}
int lower = begin;
int higher = end;
// Choose a pivot
// int pivot = zahlenliste[lower + (higher - lower) / 2];
int pivot = zahlenliste[lower + (higher - lower) / 2];
while (lower <= higher) {
while (zahlenliste[lower] < pivot) {
lower++;
}
while (zahlenliste[higher] > pivot) {
higher--;
}
if (lower < higher) {
swap(zahlenliste, lower, higher);
}
lower++;
higher--;
}
if (begin < higher) {
quickSort(begin, lower);
}
if (lower < end) {
quickSort(lower, end);
}
}
public static int[] swap(int[] zahlenliste, int begin, int end) {
int temp = zahlenliste[begin];
zahlenliste[begin] = zahlenliste[end];
zahlenliste[end] = temp;
return zahlenliste;
}
}
I know there are quicksort implementations where you choose a more fitting pivot by the median-three method or use insertion sort with lists smaller than 10. However I want to implement all of those an compare them on huge arrays. So it would be nice if anyone had a solution to get the simple quicksort to sort bigger arrays.
Upvotes: 1
Views: 235
Reputation: 28828
Fixes noted in comments
public void quickSort(int begin, int end) {
if (begin >= end) {
return;
}
int lower = begin;
int higher = end;
int pivot = zahlenliste[lower + (higher - lower) / 2];
while (lower <= higher) {
while (zahlenliste[lower] < pivot) {
lower++;
}
while (zahlenliste[higher] > pivot) {
higher--;
}
if (lower <= higher) { // fix
swap(zahlenliste, lower, higher);
lower++; // fix
higher--; // fix
}
}
if (begin < lower-1) { // fix
quickSort(begin, lower-1); // fix
}
if (lower < end) {
quickSort(lower, end);
}
}
// fix (void)
public void swap(int[] zahlenliste, int begin, int end) {
int temp = zahlenliste[begin];
zahlenliste[begin] = zahlenliste[end];
zahlenliste[end] = temp;
}
Example of a conventional Hoare partition based quick sort. It also only uses recursion on the smaller (or equal sized) partition, then iterates back to the top of the loop for the larger (or equal sized) partition:
public static void qsort(long[] a, int lo, int hi)
{
while(lo < hi){
int md = lo+(hi-lo)/2;
int ll = lo-1;
int hh = hi+1;
long p = a[md];
long t;
while(true){
while(a[++ll] < p);
while(a[--hh] > p);
if(ll >= hh)
break;
t = a[ll];
a[ll] = a[hh];
a[hh] = t;
}
ll = hh++;
// only use recursion on smaller partition,
// then loop back for larger partition
if((ll - lo) <= (hi - hh)){
qsort(a, lo, ll);
lo = hh;
} else {
qsort(a, hh, hi);
hi = ll;
}
}
}
Upvotes: 1