package com.lambda.Experiment;
import java.io.*;
import java.util.*;
/*
Demo quick sort program with a bug.
QuickSortNonThreaded 10 works correctly
QuickSortNonThreaded 11 doesn't!
*/
public class QuickSortNonThreaded {
static int MAX;
int[] array;
public static void main(String[] argv) {
int n = 10;
if (argv.length > 0) n = Integer.parseInt(argv[0]);
long start = System.currentTimeMillis();
sortNElements(n);
long end = System.currentTimeMillis();
long total = end-start;
System.out.println(""+ total + "ms");
}
public static void sortNElements(int nElements) {
MAX = nElements;
System.out.println("-------------- QuickSortNonThreaded Program ----------------");
QuickSortNonThreaded q = new QuickSortNonThreaded();
q.array = new int[MAX];
q.array[0] = 1;
for (int i=1; i < MAX; i++) q.array[i] = ((i-1)*1233)%1974;// More-or-less random
q.sortAll();
q.checkOrder();
q.printAll();
}
public void sortAll() {
sort(0, MAX-1);
}
public void checkOrder() {
for (int i=1; i < MAX; i++) {
if (array[i-1] > array[i])
System.out.println("Out of order: array[" + (i-1) + "]="+array[i-1]
+" > array["+i+"]="+array[i]);
}
}
public void printAll() {
int top = MAX;
if (MAX > 100) top=100;
for (int i=0; i < top; i++) {
System.out.println(i + "\t "+ array[i]);
}
}
// **** This will be called both recursively and from different threads. ****
public void sort(int start, int end) {
int i, j, tmp, average, middle;
if ((end - start) < 1) return; // One element, done!
if ((end - start) == 1) { // Two elements, sort directly
if (array[end] > array[start]) return;
tmp = array[start];
array[start] = array[end];
array[end] = tmp;
return;
}
average = average(start, end);
middle = end; // This will become the pivot point
L: for (i = start; i < middle; i++) { // Start the pivot:
if (array[i] > average) { // Move all values > average up,
for (j = middle; j > i; j--) {
if (array[j] <= average) { // all values <= average down.
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
middle = j; // The pivot point remains in the middle
continue L;
}
}
}
}
sort(start, middle-1); // Do the bottom half here.
sort(middle, end); // Do the top half here.
return;
}
public int average(int start, int end) {
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return (sum/(end-start));
}
}