剑指offer-快速排序

快速排序

package case99_QuickSort;

public class QuickSort {
	// 快速排序
	public static void main(String[] args) {
		int[] arr = { 9, 9, 5, 8, 3, 7, 4, 6, 2 };
		QSort(arr);
		for (int i = 0; i < arr.length; i++)
			System.out.print(arr[i] + " ");
	}

	// 快排
	public static void QSort(int[] arr) {
		if (arr == null)
			return;
		if (arr.length == 0)
			return;
		// 快排
		QS(arr, 0, arr.length - 1);
	}

	// 递归方式完成快排
	public static void QS(int[] arr, int low, int high) {
		//优化2:当数组数量较小时使用插入排序,经验值7个或者50个以下
		if (low < high) {
			// 把中枢值放到合理的位置,并且得到中枢值得位置
			int pivotPos = partition(arr, low, high);
			// 中枢值位置左侧进行递归
			QS(arr, low, pivotPos - 1);
			// 中枢值位置右侧进行递归
			QS(arr, pivotPos + 1, high);	//优化3:尾递归。因为采用了迭代,减小了栈的深度。
		}
	}

	// 获得中枢的位置
	public static int partition(int[] arr, int low, int high) {
		// 取第一个数作为中枢值	(优化1:这里可以采用三数取中优化)
		int pivotKey = arr[low];
		// 从两头开始向中间取值
		while (low < high) {
			// 从最右侧的值开始比较
			while (low < high && pivotKey <= arr[high])
				high--;
			arr[low] = arr[high];
			// 从最左侧的值开始比较
			while (low < high && pivotKey >= arr[low])
				low++;
			arr[high] = arr[low];
		}
		arr[low] = pivotKey;
		return low;
	}
}


快速排序优化版本
package case99_QuickSort;

public class QuickSortOpt {

	/**
	 * 对快排进行优化 优化1:三数取中优化 优化2:优化小数组时的排序方案 优化3:优化递归
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arr = { 9, 9, 5, 8, 3, 7, 4, 6, 2 };
		Qsort(arr);
		for (int i = 0; i < arr.length; i++)
			System.out.print(arr[i] + " ");
	}

	// 排序
	public static void Qsort(int[] arr) {
		if (arr == null)
			return;
		if (arr.length == 0)
			return;
		// 快速排序
		QS(arr, 0, arr.length - 1);
	}

	// 采用递归的方式完成排序
	public static void QS(int[] arr, int low, int high) {
		// 优化2:数组个数大于一定个数的时候,采用快速排序;否则,采用直接插入排序。
		int Distance = high - low;
		if (Distance > 7) {
			while (low < high) { // 优化3:优化递归操作
				// 获取中枢值的位置,并且完成大小数组的划分
				int pivotPos = partition(arr, low, high);
				QS(arr, low, pivotPos - 1);
				low = pivotPos + 1; // 优化3:采用迭代的方法,可以缩减栈的深度。
			}
		} else
			// 直接插入排序
			InsertSort(arr, low, high);
	}

	// 直接插入
	public static void InsertSort(int[] arr, int low, int high) {
		if (low < high) {
			for (int i = low; i < high; i++) {
				if (arr[low + 1] < arr[low]) {
					int temp = arr[low + 1];
					// 记录后移
					int j;
					for (j = low + 1; temp < arr[j]; j--) {
						arr[j] = arr[j - 1];
					}
					arr[j] = temp;
				}
			}
		}
	}

	// 获取中枢值的位置,并且完成大小数组的划分
	public static int partition(int[] arr, int low, int high) {
		// 优化1:三数取中
		int m = low + (high - low) / 2;
		if (arr[m] > arr[high]) // 小的数放到low的位置
			swap(arr, m, high);
		if (arr[low] > arr[high])
			swap(arr, low, high);
		if (arr[low] > arr[m])
			swap(arr, low, m);
		int pivotKey = arr[low];
		// 从两头向中间开始交替靠近
		while (low < high) {
			while (low < high && arr[high] >= pivotKey)
				high--;
			arr[low] = arr[high];
			while (low < high && arr[low] <= pivotKey)
				low++;
			arr[high] = arr[low];
		}
		arr[low] = pivotKey;
		return low;
	}

	// 完成low,high位置两个数的交换
	public static void swap(int[] arr, int low, int high) {
		int temp;
		if (arr[low] > arr[high]) {
			temp = arr[low];
			arr[low] = arr[high];
			arr[high] = temp;
		}
	}

}


你可能感兴趣的:(剑指offer)