Antiquicksort.
The algorithm for sorting primitive types in Java
is a variant of 3-way quicksort developed by Bentley and
McIlroy.
It is extremely efficient for most inputs that arise in
practice,
including inputs that are already sorted.
However, using a clever technique described by
M. D. McIlroy in A Killer Adversary for Quicksort,
it is possible to construct pathological inputs
that make the system sort run in quadratic time.
Even worse, it is blows the function call stack.
To see Java's sorting library break,
here are some pathological inputs of varying sizes:
10,000, 20,000, 50,000, 100,000, 250,000, 500,000, and
1,000,000.
Test them out using the program
IntegerSort.java
which takes a command line input N,
reads in N integers from standard input,
and sorts them using the system sort.
Program
IntegerSort.java
package dateoperation;
import java.util.Scanner;
public class IntegerSort {
// cutoff to insertion sort, must be >=
1
private static final int INSERTION_SORT_CUTOFF =
8;
// cutoff to median-of-3 partitioning
private static final int MEDIAN_OF_3_CUTOFF =
40;
// This class should not be
instantiated.
private IntegerSort() { }
/**
* Rearranges the array in ascending order,
using the natural order.
* @param a the array to be sorted
*/
public static void sort(Comparable[] a) {
sort(a, 0, a.length -
1);
}
private static void sort(Comparable[] a, int
lo, int hi) {
int n = hi - lo + 1;
// cutoff to
insertion sort
if (n <=
INSERTION_SORT_CUTOFF) {
insertionSort(a, lo, hi);
return;
}
// use median-of-3 as
partitioning element
else if (n <=
MEDIAN_OF_3_CUTOFF) {
int m = median3(a, lo, lo + n/2, hi);
exch(a, m, lo);
}
// use Tukey ninther
as partitioning element
else {
int eps = n/8;
int mid = lo + n/2;
int m1 = median3(a, lo, lo + eps, lo + eps + eps);
int m2 = median3(a, mid - eps, mid, mid + eps);
int m3 = median3(a, hi - eps - eps, hi - eps, hi);
int ninther = median3(a, m1, m2, m3);
exch(a, ninther, lo);
}
// Bentley-McIlroy
3-way partitioning
int i = lo, j =
hi+1;
int p = lo, q =
hi+1;
Comparable v =
a[lo];
while (true) {
while (less(a[++i], v))
if (i == hi) break;
while (less(v, a[--j]))
if (j == lo) break;
// pointers cross
if (i == j && eq(a[i], v))
exch(a, ++p, i);
if (i >= j) break;
exch(a, i, j);
if (eq(a[i], v)) exch(a, ++p, i);
if (eq(a[j], v)) exch(a, --q, j);
}
i = j + 1;
for (int k = lo; k <=
p; k++)
exch(a, k, j--);
for (int k = hi; k >=
q; k--)
exch(a, k, i++);
sort(a, lo, j);
sort(a, i, hi);
}
// sort from a[lo] to a[hi] using insertion
sort
private static void insertionSort(Comparable[]
a, int lo, int hi) {
for (int i = lo; i <=
hi; i++)
for (int j = i; j > lo && less(a[j], a[j-1]); j--)
exch(a, j, j-1);
}
// return the index of the median element among
a[i], a[j], and a[k]
private static int median3(Comparable[] a, int
i, int j, int k) {
return (less(a[i], a[j])
?
(less(a[j], a[k]) ? j : less(a[i], a[k]) ? k : i) :
(less(a[k], a[j]) ? j : less(a[k], a[i]) ? k : i));
}
/***************************************************************************
* Helper sorting functions.
***************************************************************************/
// is v < w ?
private static boolean less(Comparable v,
Comparable w) {
if (v == w) return
false; // optimization when reference equal
return v.compareTo(w)
< 0;
}
// does v == w ?
private static boolean eq(Comparable v,
Comparable w) {
if (v == w) return
true; // optimization when reference equal
return v.compareTo(w) ==
0;
}
// exchange a[i] and a[j]
private static void exch(Object[] a, int i, int
j) {
Object swap =
a[i];
a[i] = a[j];
a[j] = swap;
}
/***************************************************************************
* Check if array is sorted - useful for
debugging.
***************************************************************************/
private static boolean isSorted(Comparable[] a)
{
for (int i = 1; i <
a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i <
a.length; i++) {
System.out.println(a[i]);
//StdOut.println(a[i]);
}
}
/**
* Reads in a sequence of strings from
standard input; quicksorts them
* (using an optimized version of
quicksort);
* and prints them to standard output in
ascending order.
*
* @param args the command-line
arguments
*/
public static void main(String[] args) {
Scanner scanner=new
Scanner(System.in);
System.out.println("Enter the size of Integer number");
int
n=scanner.nextInt();
Integer a[]=new
Integer[n];
System.out.println("Enter Integer Number for Array");
for (int i = 0; i <
a.length; i++) {
a[i]=scanner.nextInt();
}
IntegerSort.sort(a);
assert
isSorted(a);
System.out.println("Sorted Elements are");
show(a);
}
}
/*
output:
run:
Enter the size of Integer number
6
Enter Integer Number for Array
8
1
4
5
9
3
Sorted Elements are
1
3
4
5
8
9
*/
Antiquicksort. The algorithm for sorting primitive types in Java is a variant of 3-way quicksort developed...
I need the report like this (idea) *Sorting Algorithms: A sorting algorithm is an algorithm that puts elements of a list in a certain order. The most-used orders are numerical order and lexicographical order. Efficient sorting is important for optimizing the use of other algorithms (such as search and merge algorithms) which require input data to be in sorted lists; it is also often useful for canonical zing data and for producing human-readable output. More formally, the output must satisfy...