論java快速排序

public class QuickSort {

	public static void main(String[] args) {
		QuickSort sorter = new QuickSort();

		int src[] = { 10, 9,8,7,6,5,4,3};

		sorter.quickSort(src, 0, src.length-1, 3);

		for (int i : src) {
			System.out.print(i + " ");
		}
	}

	/**
	 * 
	 * @param src
	 * @param first
	 * @param last
	 * @param minSortNum
	 *            當最小值爲多少的時候不再進行快速排序,而是直接用插入排序來解決
	 */
	private void quickSort(int[] src, int first, int last, int minSortNum) {
		if (last - first + 1 <= minSortNum) {
			insertSort(src, first, last);
			return;
		}

		int pivotIndex = partition(src, first, last);//對數組實現劃分
		quickSort(src, first, pivotIndex, minSortNum);
		quickSort(src, pivotIndex + 1, last, minSortNum);
	}

	/**
	 * 插入排序的代碼
	 * 
	 * @param src
	 * @param first
	 * @param last
	 */
	private void insertSort(int[] src, int first, int last) {
		for (int i = first + 1; i <= last - first; ++i) {
			int temp = src[i];
			int j = i;
			while (j > 0 && src[j - 1] > temp) {
				src[j] = src[j - 1];
				j--;
			}
			src[j] = temp;
		}

	}

	/**
	 * Task:讓支點前所有的元素都比支點小,支點後所有的元素都比支點大
	 * 從第二個元素向右尋找,從倒數第三個元素開始向前尋找(因爲支點在之前已經被交換到倒數第二個元素,所以倒數第二個元素無需比較)
	 * 
	 * 如果下標爲IndexFromLeft的元素小於下標爲IndexFromRight的元素,並且IndexFromLeft<IndexFromRight,那麼將其交換位置
	 * 因爲向右最終將到達支點處,所以不用考慮出界的問題
	 * @param src
	 * @param first
	 * @param last
	 * @return支點的下標
	 */
	private int partition(int[] src, int first, int last) {
		int mid = findPivot(src, first, last);
		int pivotNum = src[mid];//得到支點的數值
		swap(src, mid, last - 1);//將支點與倒數第二個元素進行交換

		
		int indexFromLeft = first + 1;//設置最開始查找的元素爲第一個,因爲第0個元素一定比支點小
		int indexFromRight = last - 2;
		boolean done = false;
		while (!done) {
			while (src[indexFromLeft] < pivotNum) {
				indexFromLeft++;
			}
			while (src[indexFromRight] > pivotNum) {
				indexFromRight--;
			}

			if (indexFromLeft < indexFromRight) {
				swap(src, indexFromLeft, indexFromRight);
				indexFromLeft++;
				indexFromRight--;
			} else {
				done = true;
			}
		}

		swap(src, last - 1, indexFromLeft);
		int pivotInex = indexFromLeft;
		return pivotInex;
	}

	//排序兩個元素
	private void sort2Element(int[] src, int one, int two) {

		if (src[one] > src[two]) {
			swap(src, one, two);
		}
	}

	/**
	 * 支點爲前中後三個元素的排序,將其排序後在中間的元素即爲支點,將這三個元素按照大小順序排序好(進行交換)
	 */
	private int findPivot(int[] src, int first, int last) {
		int mid = (first + last) / 2;
		sort2Element(src, first, mid);
		sort2Element(src, mid, last);
		sort2Element(src, first, mid);
		return mid;
	}

	private void swap(int[] src, int one, int two) {
		int temp = 0;
		temp = src[one];
		src[one] = src[two];
		src[two] = temp;
	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章