快速排序(Java实现)

快速排序的算法思路:

快速排序中,算法对数组进行重新整理分割成两个子数组,对两个子数组进行排序,当两个子数组是有序时,整个数组即为有序的。


下面给出具体代码:

package javastudy;

public class QuickSort {
	public void quickSort(int[] A, int n) {
		// 快速排序

		qSort(A, 0, n - 1);
  

	}

	public void qSort(int[] A, int left, int right) {

		// 枢轴
		int pivot;
		if (left < right) {
            /**
             *   pivot的初值:为切割点(第一次排完序后切割点的位置)
             */
			pivot = partition(A, left, right);
            /**
             * 以此切割点为基础 左边的比切割点小 右边的比切割点大 进行递归排序
             */
			qSort(A, left, pivot - 1);
			qSort(A, pivot + 1, right);

		}

	}

	/**partition是寻找到第一次排序后的被当做切割点元素的位置(这个元素的位置也就是最后排完序的位置)
	 * 需要注意到:这个元素的选取通过median3函数来确定
	 * 当确定这个元素的位置后,我们仅仅只是排完一次序,并没有达到我们最后的效果
	 */
	
	public int partition(int[] A, int left, int right) {

		/** 优化选取元素,采用三数取中的方法来确定开始要选取的那个元素
		 *  也就是被当做切割点的元素的值
		 */
		int pivotKey = median3(A, left, right);
		/**
		 * while(left<right)这是个大的前提,当low等于high的时候,证明一次的排序结束
		 */
		while (left < right) {
			/**
			 * 这里的low<high一定要加 不然就超出整个数组范围,程序会标报错
			 */
			while (left < right && A[right] >= pivotKey) {
				right--;
			}
			/**
			 * 条件:A[hight]< pivotKey
			 */
			A[left] = A[right];
			while (left < right && A[left] <= pivotKey) {
				left++;
			}
			/**
			 * 条件:A[left]> pivotKey
			 */
			A[right] = A[left];

		}

	    /**
	     *  循环结束的时候:low一定和high是相等的,然后把切割点val的值赋给循环跳出来的a[low]或者a[high]都行
	     */
		A[left] = pivotKey;
		/**
		 * 返回此时这个切割点元素的下标
		 */
		return left;
	}

	// 通过三数取中来确定基数(切割点的元素)
	public int median3(int[] A, int left, int right) {

		int mid = (right - left) / 2;
		if (A[left] > A[right]) {
			swap(A, left, right);
		}
		if (A[mid] > A[left]) {
			swap(A, mid, left);
		}
		if (A[mid] > A[right]) {
			swap(A, mid, right);
		}

		return A[left];
	}

	public void swap(int[] A, int i, int j) {
		int temp = A[i];
		A[i] = A[j];
		A[j] = temp;
	}

}

主函数测试一下:

package javastudy;

public class MainTest {

	public static void main(String[] args) {

		QuickSort sort = new QuickSort();
		int A[] = { -2, -5, -1, -88, 9 };
		sort.qSort(A, 0, A.length - 1);
		for (int i : A) {
			System.out.print(i + " ");
		}
	}

}
  • 快速排序

  • 时间性能取决于递归的深度,可以用递归树来描述递归算法的执行情况!最优情况下,partition每次划分均匀,排序n个数值,则递归树的深度为[logn]+1,第一次partition需要对整个数组扫描一遍,做n次比较,第二次对一半扫描。所以最优时间复杂度 Ο(n log n) ,最差时间复杂度 Ο(n^2) ,平均时间复杂度Ο(n log n) 。

  • 递归导致栈空间的使用,最好空间复杂度为Ο(log n),最差空间复杂度Ο(n)。


猜你喜欢

转载自blog.csdn.net/qq_32575047/article/details/80467892