給定一個序列:22 33 49 47 33' 12 68 29
ios
進行快速排序算法
從序列中,任選一個記錄k
做爲軸值 pivot
數組
選擇策略:ui
將剩餘的元素,分割成 左子序列 L 和 右子序列 Rspa
L 中全部元素都 < k, R 中全部元素都 > k指針
對 L 和 R遞歸進行快排,直到子序列中有 0 個 或者 1 個元素,退出code
初始數組:排序
選定47
爲軸值pivot
遞歸
pivot
與最後一個值29
進行交換(把pivot
放到最後面)string
接下來,以pivot=47
爲界,分紅左子序列 L
和右子序列 R
比47
大的都放在右邊,比47
小的都放在左邊(用的交換)
遍歷數組
left
和right
left != right
的時候
arr[left]
的,小於等於pivot
,且left < right
的時候,left
右移
left
和right
未相遇,把left
的值賦給right
對應的值arr[right] = arr[left]
left
指針中止移動,輪到right
移動arr[right]
的值,大於等於pivot
,且right > left
的時候,right
左移
left
和right
未相遇。把right
的值賦給left
對應的值arr[left] = arr[right]
right
指針中止移動,輪到left
移動pivot
保存pivot=47
和最後一個值互換
22 <= 47
,left
向右移動
33 <= 47
,left
向右移動
49 > 47
,不知足arr[left] <= pivot
把left
的值賦給right
arr[right] = arr[left]
賦值事後,left
不動,right
向左移動
68 >= 47
,right向左移動
12 < 47
,不知足arr[right] >= pivot
把right
的值賦給left
arr[left] = arr[right]
賦值事後,right
不動,left
向右移動
29 < 47
,left
向右移動
33' < 47
,left
向右移動
向右移動後,left == right
,退出循環
將pivot
賦給arr[left]
至此,第一輪分割序列完成
通過第一輪分割,47
左邊的是左子序列,右邊是右子序列
第二輪對左子序列分割,選擇中間值做爲pivot
12和33'
進行交換
22 > 12
,不知足arr[left] <= pivot
把arr[left]
賦給arr[right]
arr[right] = arr[left]
賦值事後,left
不動,right
向左移動
2九、33'、33
都比12
大,因此right
一直移動到下圖位置
33 > 12
,right
繼續向左移動
此時right == left
,終止循環
把pivot
賦給arr[left]
至此,左子序列1也分割完成了
快排就是一個遞歸的過程,分割獲得左子序列
再對左子序列進行快排分割,獲得左子序列的左子序列....
處理完左邊,再去處理右邊的右子序列
右子序列只有4七、6八、49
,選擇48
做爲軸值 pivot
pivot
和最後一個值交換
4七、49
都比pivot=68
小,left
一直向右移動,直到left == right
分割以後,只剩下左子序列:4七、49
4七、49
,選49
做爲軸值,獲得左子序列47
子序列只剩下一個元素47
,就沒必要排序了,右邊排序結束
結果:4七、4九、68
選擇中間的值做爲軸值
#include <iostream> #include <vector> #include <algorithm> #include <unordered_map> #include <unordered_set> #include <string> #include <stack> #include <cmath> #include <map> using namespace std; /** * * @param arr 待分割的序列 * @param left 左邊界 * @param right 右邊界 * @return 分割後軸值的位置 */ template<class T> int PartitionArr(vector<T>& arr, int left, int right) { T temp = arr[right]; while (left != right) { while (arr[left] <= temp && left < right) { left++; } if (left < right) { arr[right] = arr[left]; // 賦值後,left不動,right向左移 right--; } while (arr[right] >= temp && right > left) { right--; } if (left < right) { arr[left] = arr[right]; // 賦值後,right不動,left向右移 left++; } } // 當left == right,把軸值放回left上 arr[left] = temp; return left; } /** * * @param arr 待排序數組 * @param left 左邊界 * @param right 右邊界 */ template<class T> void quickSort(vector<T>& arr, int left, int right) { // 子序列剩下0或1個元素,排序結束 if (right <= left) { return; } // 選擇數組中間做爲軸值 int pivot = (left + right) / 2; // 把軸值放到數組最後面 swap(arr[right], arr[pivot]); // 分割後軸值的位置 // 分割後,左邊值 < 軸值 < 右邊值 pivot = PartitionArr(arr, left, right); quickSort(arr, left, pivot - 1); quickSort(arr, pivot + 1, right); } int main() { vector<int> arr = { 22,33,49,47,33,12,68,29 }; for (auto& i : arr) { cout << i << ' '; } cout << endl << endl; quickSort(arr, 0, arr.size() - 1); for (auto& i : arr) { cout << i << ' '; } cout << endl << endl; system("pause"); return 0; }
快排是不穩定的排序算法
33 33'
排序後可能變成33' 33
時間複雜度:
空間複雜度: