Mega Code Archive

 
Categories / Java / Collections Data Structure
 

Quicksort implementation for sorting arrays

/*  * Copyright (c) 1998 - 2005 Versant Corporation  * All rights reserved. This program and the accompanying materials  * are made available under the terms of the Eclipse Public License v1.0  * which accompanies this distribution, and is available at  * http://www.eclipse.org/legal/epl-v10.html  *  * Contributors:  * Versant Corporation - initial API and implementation  */ import java.util.Comparator; /**   * Quicksort implementation for sorting arrays. Unlike the merge sort in  * java.utils.Collections this one does not create any objects. There are  * two implementations, one for arrays of Comparable's and another that  * uses a comparator.  */ public class Quicksort {     private Quicksort() {     }     /**      * Sort the first size entries in a.      */     public static void quicksort(Object[] a, int size) {         quicksort(a, 0, size - 1);     }     /**      * Sort the entries in a between left and right inclusive.      */     public static void quicksort(Object[] a, int left, int right) {         int size = right - left + 1;         switch (size) {             case 0:             case 1:                 break;             case 2:                 if (compare(a[left], a[right]) > 0) swap(a, left, right);                 break;             case 3:                 if (compare(a[left], a[right - 1]) > 0) swap(a, left, right - 1);                 if (compare(a[left], a[right]) > 0) swap(a, left, right);                 if (compare(a[left + 1], a[right]) > 0) swap(a, left + 1, right);                 break;             default:                 int median = median(a, left, right);                 int partition = partition(a, left, right, median);                 quicksort(a, left, partition - 1);                 quicksort(a, partition + 1, right);         }     }     private static int compare(Object a, Object b) {         if (a == null) {             return b == null ? 0 : -1;         } else if (b == null) {             return +1;         } else {             return ((Comparable)a).compareTo(b);         }     }     private static void swap(Object[] a, int left, int right) {         Object t = a[left];         a[left] = a[right];         a[right] = t;     }     private static int median(Object[] a, int left, int right) {         int center = (left + right) / 2;         if (compare(a[left], a[center]) > 0) swap(a, left, center);         if (compare(a[left], a[right]) > 0) swap(a, left, right);         if (compare(a[center], a[right]) > 0) swap(a, center, right);         swap(a, center, right - 1);         return right - 1;     }     private static int partition(Object[] a, int left, int right, int pivotIndex) {         int leftIndex = left;         int rightIndex = right - 1;         while (true) {             while (compare(a[++leftIndex], a[pivotIndex]) < 0);             while (compare(a[--rightIndex], a[pivotIndex]) > 0);             if (leftIndex >= rightIndex) {                 break; // pointers cross so partition done             } else {                 swap(a, leftIndex, rightIndex);             }         }         swap(a, leftIndex, right - 1);         // restore pivot         return leftIndex;                 // return pivot location     }     /**      * Sort the first size entries in a.      */     public static void quicksort(Object[] a, int size, Comparator c) {         quicksort(a, 0, size - 1, c);     }     /**      * Sort the entries in a between left and right inclusive.      */     public static void quicksort(Object[] a, int left, int right, Comparator c) {         int size = right - left + 1;         switch (size) {             case 0:             case 1:                 break;             case 2:                 if (c.compare(a[left], a[right]) > 0) swap(a, left, right);                 break;             case 3:                 if (c.compare(a[left], a[right - 1]) > 0) swap(a, left, right - 1);                 if (c.compare(a[left], a[right]) > 0) swap(a, left, right);                 if (c.compare(a[left + 1], a[right]) > 0) swap(a, left + 1, right);                 break;             default:                 int median = median(a, left, right, c);                 int partition = partition(a, left, right, median, c);                 quicksort(a, left, partition - 1, c);                 quicksort(a, partition + 1, right, c);         }     }     private static int median(Object[] a, int left, int right, Comparator c) {         int center = (left + right) / 2;         if (c.compare(a[left], a[center]) > 0) swap(a, left, center);         if (c.compare(a[left], a[right]) > 0) swap(a, left, right);         if (c.compare(a[center], a[right]) > 0) swap(a, center, right);         swap(a, center, right - 1);         return right - 1;     }     private static int partition(Object[] a, int left, int right,             int pivotIndex, Comparator c) {         int leftIndex = left;         int rightIndex = right - 1;         while (true) {             while (c.compare(a[++leftIndex], a[pivotIndex]) < 0);             while (c.compare(a[--rightIndex], a[pivotIndex]) > 0);             if (leftIndex >= rightIndex) {                 break; // pointers cross so partition done             } else {                 swap(a, leftIndex, rightIndex);             }         }         swap(a, leftIndex, right - 1);         // restore pivot         return leftIndex;                 // return pivot location     } }