Quicksort.java Source code

Java tutorial

Introduction

Here is the source code for Quicksort.java

Source

/*
 * 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
    }

}