iT邦幫忙

2021 iThome 鐵人賽

DAY 25
0
Software Development

程式菜鳥自學C++資料結構演算法系列 第 25

[Day25]程式菜鳥自學C++資料結構演算法 – 快速排序法(Quick Sort)

  • 分享至 

  • xImage
  •  

前言:講解完了基礎的排序法後,接著要來講解比較高等的排序法,今天和明天要介紹的都是始於分割資料的排序法,就先從快速排序開始講起。

分割資料的排序法:這類型的排序法,主要是用**「各個擊破」(Divide-and-Conquer)分治演算法**,這種演算法是將排序問題分割成多個小問題,在使用遞迴的方式逐一解決各個子問題後所完成的排序法。

快速排序法:

是目前公認最佳的排序法,雖然和基礎的氣泡排序一樣,都是採用交換的方式進行排序,但是透過分割的技巧,使得快速排序的執行效率遠大於氣泡排序。
分割資料的方式是選擇一個鍵值作為分割標準,將鍵值分成兩半的兩個集合,一半是比標準值還要大的鍵值集合,另一半是較小或相等的集合。
接著每一半的鍵值使用相同的分割法,直到無法繼續分割,此時所有的鍵值以排序完成。

如何挑選基準值?常用的分式可以取亂數或是取數列的最左或最右邊,也可以用比較進階的方式,取數列的第一、中間和最後一個數,取第二大的當基準值也可以。
https://ithelp.ithome.com.tw/upload/images/20211009/20140187jiJ6CGbgXX.png

https://ithelp.ithome.com.tw/upload/images/20211009/201401872qhqUge1VL.png

因為快速排序需要使用遞迴函式,所以要有額外的記憶體空間來處理遞迴方法。屬於不穩定的排序法,因為排序元素會進行分割和交換,所以有可能會交換到相同鍵值的元素。

快速排序實作:
https://ithelp.ithome.com.tw/upload/images/20211009/20140187zVfMSMg77a.png

這樣就完成了!
https://ithelp.ithome.com.tw/upload/images/20211009/201401870PP3YXii9i.png

本日小結:快速排序雖然是很有效率的排序法,不過很顯而易見的並沒有像基礎排序法那樣的直觀簡單好理解,而且如果遇到最糟的情況下會慢上很多,但快速排序依舊是非常重要的,還是學起來會比較好,明天要介紹同樣為分割排序「合併排序法」Ꮚ^ꈊ^Ꮚ

template <typename T>
int Partition(vector<T>& a, int L, int H) { //編寫快速排序的劃分
	T t = a[L]; //把最左邊的元素當作基準值
	while (L < H) {
		print(a);
		//H向左,直到遇見比基準值小的
		while (L < H && !(a[H] < t))
			H--;
		a[L] = a[H];
		//L向右,直到遇見比基準值大的
		while (L < H && a[L] < t)
			L++;
		a[H] = a[L];
	}
	a[L] = t;
	return L;
}

template <typename T>
void quick_sort(vector<T>& a, int L, int H) { //編寫快速排序的過程
	if (L < H) { //待排序數列長度需大於1
		int pivotloc = Partition(a, L, H);
		//對左子集進行快速排序
		quick_sort(a, L, pivotloc - 1);
		//對右子集進行快速排序
		quick_sort(a, pivotloc + 1, H);
	}
}

上一篇
[Day24]程式菜鳥自學C++資料結構演算法 – 選擇排序法(Selection Sort)和謝爾排序法(Shell Sort)
下一篇
[Day26]程式菜鳥自學C++資料結構演算法 – 合併排序法(Merge Sort)
系列文
程式菜鳥自學C++資料結構演算法30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言