Location: PHPKode > scripts > Enhanced QuickSort > enhanced-quicksort/quicksort.php
<?php

/**
 * QuickSort performs an enhanced quicksort on an array of comparable data.
 * Comparable data is typically integers, floats, doubles, or strings which 
 * should compare as integer values. The enhancement mentioned is the use of
 * an Insertion sort algorithm when a predefined cutoff limit has been reached.
 * The cutoff improves the speed of QuickSort when it reaches small unsorted arrays.
 * The qsort algorithm used is modified from Wikipedia's C implementation of QuickSort.
 * See this implementation here: http://en.wikipedia.org/wiki/Quicksort
 *
 * @copyright BSD license - You may change, use, distribute freely, but you cannot sell this class.
 */
class QuickSort{

	/**
	 * QuickSort constructor.
	 * @param $array - An unsorted array of comparable data.
	 */
	function QuickSort($array){
		$this->unsorted = $array;
	}
	
	/**
	 * This is a standard setter for recycling this class.
	 * You can set the array to another array and resort and get the
	 * newly sorted array again.
	 * @param $array - An unsorted array of comparable data.
	 */
	function setArray($array){
		$this->unsorted = $array;
	}
	
	/**
	 * sortArray sorts the array which was loaded in the constructor. A cutoff of 1500
	 * is used to switch the quicksort algorithm to a insertion sort algorithm. 1500 was
	 * determined to be the optimal number for any input size. If the input is smaller than 1500
	 * items then only insertion sort will be used.
	 */
	function sortArray(){
		$this->sorted = $this->qsort( $this->unsorted,0,count($this->unsorted),1500 );
	}
	
	/**
	 * getSortedArray returns the sorted array after the sortArray
	 * function has been called. It will return NULL if the sortArray function
	 * has not been called.
	 * @return The sorted array
	 */
	function getSortedArray(){
		return $this->sorted;
	}
	
	/**
	 * doSortAndGetSortedArray is the lazy-man's function
	 * for performing the sort on the pre-loaded array 
	 * (load the array in the constructor) and returning the 
	 * sorted array. To use this function just load the array in the 
	 * constructor and call this method. The sorted array is returned.
	 * @return The sorted array.
	 */
	function doSortAndGetSortedArray(){
		$this->sortArray();
		return $this->getSortedArray();
	}
	
	/**
	 * @private
	 * qsort is a private function which performs all of the sorting work.
	 * It takes an array which is passed by reference and recursively breaks
	 * the array into smaller and smaller sub parts. It sorts the sub parts
	 * around a pivot point and breaks those sub parts by the pivot and recursively 
	 * calling qsort again. A cutOff is used to limit the qsort algorithm, because 
	 * qsort doesn't work very well with small input an insertion sort algorithm is used.
	 * @param $array - An array of comparable data (ints, floats, doubles, or strings compared by int value).
	 * @param $lowPos - A position to start sorting at. First sort call usually starts at 0.
	 * @param $highPos - A position to end sorting at. First sort call usually ends at count($array).
	 * @param $cutOff - A cutoff point to switch to Insertion sort. 1500 is a good position.
	 */
	function qsort(&$array, $lowPos, $highPos, $cutOff){
		if($lowPos + $cutOff > $highPos){
			$this->insertionSort($array,$lowPos,$highPos);
		}else{
			$left = $lowPos;
			$right = $highPos;
			$pivot = $array[$left];
			while ($left < $right){
				while (($array[$right] >= $pivot) && ($left < $right))
					$right--;
				if ($left != $right){
					$array[$left] = $array[$right];
					$left++;
				}
				while (($array[$left] <= $pivot) && ($left < $right))
					$left++;
				if ($left != $right){
					$array[$right] = $array[$left];
					$right--;
				}
			}
			$array[$left] = $pivot;
			$pivot = $left;
			if ($lowPos < $pivot)
				$this->qsort($array, $lowPos, $pivot, $cutOff);
			if ($highPos > $pivot)
				$this->qsort($array, $pivot+1, $highPos, $cutOff);
		}
		return $array;
	}
	
	/**
	 * insertionSort algorithm developed by Allan Bogh.
	 * This algorithm was developed specifically by Allan Bogh from scratch.
	 * It is a simple pull-out-and-insert-into-position algorithm, but it 
	 * may not exactly follow the true Insertion Sort method.
	 * @param $array - An array of numbers, passed by reference
	 * @param $low - A key specifying the starting point.
	 * @param $high - A key specifying the ending point.
	 * @return The sorted array, not used in pass by reference situations.
	 */
	function insertionSort(&$array, $low, $high){
		$i = $low+1;

		while ($i < $high) {
			//insert(a, i, a[i]);
			$j = $i - 1;
			$value = $array[$i];
			while ($j >= $low && $array[$j] > $value) {
				$array[($j + 1)] = $array[$j];
				$j--;
			}
			$array[$j + 1] = $value;
			$i++;
		}
		 
		return $array; //don't really need this in a pass by reference situation
	}
}

?>
Return current item: Enhanced QuickSort