1. 程式人生 > 實用技巧 >【C++】快速排序

【C++】快速排序

效能分析:

  時間複雜度:O(n*log(n))

  空間複雜度:O(log(n))

這裡的時間複雜度其實是快速排序最好的時間複雜度,最壞的時間複雜度是O(n^2)

程式碼裡補充的隨機化快速排序的期望時間複雜度為:O(n*log(n))

快速排序的效能優於歸併排序是因為常數項,即演算法所需的固定時間量。

#include<iostream>
#include<vector>
#include<algorithm>
#include<random>
#include<ctime>
using namespace std;
int partition(vector<int
>& data, int left, int right); void quick_sort(vector<int>& data, int left, int right); int main() { // 思想: // 在元素序列上直接操作; // 每次在無序序列中選取一個數,一般稱之為中軸數, // 將元素序列分成兩個部分,使得一部分的元素全都小於等於另一部分的所有元素; // 也就是說將序列分成小於等於中軸數和大於等於中軸數的兩部分,使得中軸數變為有序; // 再遞迴的對分成的兩部分進行劃分操作,分到1的時候就是天然有序的了
// 改進的思想是:每次隨機找一箇中軸數,將其交換到末尾,然後再往下 vector<int> data = { 7,5,6,4 }; //獲取序列元素個數 int length = data.size(); int left = 0; int right = 3; vector<int> result; quick_sort(data, left, right); for (int i = 0; i < length; i++) { cout << data.at(i) << "
"; } } void quick_sort(vector<int>& data, int left, int right) { if (left < right) { //找到中軸數的索引 int index = partition(data, left, right); //以中軸數的索引為界遞迴的處理兩個部分的序列 quick_sort(data, left, index - 1); quick_sort(data, index + 1, right); } } int partition(vector<int>& data, int left, int right) { // 找到中軸數的正確位置,同時將序列劃分為兩部分. // 中軸數有很多種取法,我們這裡採用《演算法導論》裡的選取方法,即取序列最後一個元素. int key = data.at(right); // 此處設定兩個索引i和j,區間[left,i]為小於中軸數的序列, // 區間[j,right-1]為大於中軸數的序列. /*這裡有一種優化的方法,就是這個中軸數隨機的找,然後交換到末尾,再往下執行*/ /* default_random_engine e(time(0)); //時間引擎 uniform_int_distribution<signed> u(left, right); int key = u(e); int tem = data.at(key); data.at(key) = data.at(right); data.at(right) = tem; int ave = data.at(right); */ int i = left - 1; for (int j = left; j < right; j++)//迴圈判斷操作除了最右邊基準值外的其他元素 { if (data.at(j) <= key) { // 大於中軸數的元素讓它繼續待在[j,right-1]區間什麼也不做; // 小於中軸數的元素全部從[j,right-1]區間放到[left,i]區間去. ++i; int temp = data.at(i); data.at(i) = data.at(j); data.at(j) = temp; } } // 此時中軸數的正確位置應該在i+1,將其歸位. // 思考為什麼是i+1而不是i. int temp = data.at(i + 1); data.at(i + 1) = data.at(right); data.at(right) = temp; // 返回中軸數的正確索引. return i + 1; }