排序算法——快速排序原理解析

快速排序原理

快速排序算法通過多次比較和交換來實現排序,其排序流程如下:

  • 首先設定一個分界值,通過該分界值將數組分成左右兩部分。
  • 將大於或等於分界值的數據集中到數組右邊,小於分界值的數據集中到數組的左邊。此時,左邊部分中各元素都小於或等於分界值,而右邊部分中各元素都大於或等於分界值。
  • 然後,左邊和右邊的數據可以獨立排序。對於左側的數組數據,又可以取一個分界值,將該部分數據分成左右兩部分,同樣在左邊放置較小值,右邊放置較大值。右側的數組數據也可以做類似處理。
  • 重複上述過程,可以看出,這是一個遞歸定義。通過遞歸將左側部分排好序後,再遞歸排好右側部分的順序。當左、右兩個部分各數據排序完成後,整個數組的排序也就完成了。

舉例分析

在這裏插入圖片描述
選取上述數組的第一個元素6作爲基準元,左遊標是 i 哨兵,右遊標是 j 哨兵,它們遵循的規則如下:
一、左遊標向右掃描, 跨過所有小於基準元素的數組元素, 直到遇到一個大於或等於基準元素的數組元素, 在那個位置停下。二、右遊標向左掃描, 跨過所有大於基準元素的數組元素, 直到遇到一個小於或等於基準元素的數組元素,在那個位置停下。

第一步:哨兵 j 先開始出動。因爲此處設置的基準數是最左邊的數,所以需要讓哨兵 j 先開始出動,哨兵 j 逐步向左挪動,直到找到一個小於 6 的元素停下來。接下來哨兵 i 再逐步向右挪動,直到找到一個大於 6 的元素停下來。最後哨兵 i 停在了數字 7 面前,哨兵 j 停在了數字 5 面前。
在這裏插入圖片描述
到此第一次交換結束,接着哨兵 j 繼續向左移動,它發現 4 比基準數 6 要小,那麼在數字4面前停下來。哨兵 i 也接着向右移動,然後在數字 9 面前停下來,然後哨兵 i 和 哨兵 j 再次進行交換。
在這裏插入圖片描述
第二次交換結束,哨兵 j 繼續向左移動,然後在數字 3 面前停下來;哨兵 i 繼續向右移動,但是它發現和哨兵 j 相遇了。那麼此時說明探測結束,將數字 3 和基準數字 6 進行交換。
在這裏插入圖片描述
到此第一趟探測真正結束,此時以基準點6爲分界線,左邊的數組元素都小於等於6,右邊的數組元素都大於等於6。左邊序列爲3,1,2,5,4。右邊序列爲9,7,10,8。此時對於左邊序列而言,以數字3爲基準元素,重複上面的探測,探測完畢之後的序列爲2,1,3,5,4。對於右邊序列而言,以數字9爲基準元素,也重複上面的探測,一步一步的劃分最後排序完全結束。

複雜度

時間複雜度:最好情況(待排序列接近無序)時間複雜度爲O(nlog2n),最壞情況(待排序列接近有序)時間複雜度爲O(n2),平均時間複雜度爲O(nlog2n)。

代碼實現

public void quickSort(int[] arr, int left, int right) {

		// 當左邊大於於右邊的時候直接返回
		if (right <= left)
			return;
		int key = arr[left];// 進行劃分的值
		int i = left, j = right;//
		while (i < j) {

			// 在右邊找到第一個比key小的值
			while (i < j && arr[j] >= key) {
				j--;
			}
			// 在左邊找到第一個比key大的值
			while (i < j && arr[i] <= key) {
				i++;
			}
			if (i < j) {
				exch(arr, i, j);
			}

		}
		// 這個時候i和j已經是相等的了,j右邊的元素都不小於key,所以把key和j所對應的元素直接交換位置就行了,接下來就是將key放到相應的位置。
		exch(arr, left, j);
		quickSort(arr, left, i - 1);
		quickSort(arr, i + 1, right);

	}

	public void exch(int[] arr, int i, int j) {
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}

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