【圖解排序】快速排序(Java)

前言

嘮叨一下:半夜實在睡不着,起牀敲了一個 快速排序 的代碼,講真這是大學第一次親手敲出這個代碼,代碼使用Java實現,但算法和數據結構一樣,其本身和編程語言是沒有關係的。

簡單介紹

算法思想

基於分治的思想,是 冒泡排序 的改進型。

1.首先在數組中選擇一個基準點
(該基準點的選取可能影響快速排序的效率,後面講解選取的方法);

2.然後分別從數組的兩端掃描數組,設兩個指示標誌
low 指向起始位置,high 指向末尾);

3.首先從後半部分開始,如果發現有元素比該基準點的值小,就交換lowhigh位置的值,然後從前半部分開始搜索,發現有元素大於基準點的值,就交換lowhigh位置的值,如此往復循環,直到 low>=high,然後把基準點的值放到high這個位置。

一次排序就完成了。

以後採用遞歸的方式分別對前半部分和後半部分排序,當前半部分和後半部分均有序時該數組就自然有序了。


在這裏插入圖片描述

算法特點

快速排序的時間主要耗費在劃分操作上,對長度爲k的區間進行劃分,共需k-1次關鍵字的比較;

最壞情況
每次劃分選取的基準都是當前無序區中關鍵字最小(或最大)的記錄,劃分的結果是基準左邊的子區間爲空(或右邊的子區間爲空),而劃分所得的另一個非空的子區間中記錄數目,僅僅比劃分前的無序區中記錄個數減少一個。時間複雜度爲O(n2)

最好情況
每次劃分所取的基準都是當前無序區的"中值"記錄,劃分的結果是基準的左、右兩個無序子區間的長度大致相等。總的關鍵字比較次數:O(nlogn)
儘管快速排序的最壞時間爲O(n2),但就平均性能而言,它是基於關鍵字比較的內部排序算法中速度最快者,快速排序亦因此而得名。它的平均時間複雜度爲O(nlogn)

源碼

package nono.sort;

import java.util.Arrays;

/**
 * 快速排序
 * 
 * @author Nonoas
 */
public class QuikSorter {
	/**
	 * 快速排序
	 * 
	 * @param arry 進行排序的數組
	 * @param low  數組的起始下標
	 * @param high 數組的終止下標
	 */
	public static void quikSort(int[] arry, int low, int high) {
		if (low >= high)
			return; // 遞歸出口,當起始下標大於等於終止下標時,結束排序
		int temp = arry[low]; // 臨時變量用於保存參考元素的值
		int left = low; // 左端指針
		int rigth = high; // 右端指針

		while (left < rigth) {// 當左標小於右標時執行循環
			while (left < rigth && arry[rigth] > temp)
				rigth--; // 從後往前搜索小於中間值的數
			if (left < rigth)
				arry[left++] = arry[rigth]; // 將小於中間值的數移到左邊,這裏不用交換值,直接覆蓋即可
			while (left < rigth && arry[left] < temp)
				left++; // 從前往後搜索大於中間值的數
			if (left < rigth)
				arry[rigth--] = arry[left]; // 將大於中間值的數移到右邊,這裏不用交換值,直接覆蓋即可
		}
		// 循環體結束,說明左標與右標相遇
		arry[left] = temp;// 將參考值賦給當前位置的數,此時左邊的數都小於temp,右邊的數都大於temp
		
		quikSort(arry, low, left - 1);// 遞歸排序左部
		quikSort(arry, rigth + 1, high);// 遞歸排序右部
	}

	public static void main(String[] args) {
		int[] a = { 8, 7, 6, 3, 5, 4 };
		System.out.println("排序前:" + Arrays.toString(a));
		QuikSorter.quikSort(a, 0, a.length - 1);
		System.out.println("排序後:" + Arrays.toString(a));
	}
}

運行結果

在這裏插入圖片描述

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