论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;
	}

}

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