1. 程式人生 > 實用技巧 >快速排序C++ 遞迴實現

快速排序C++ 遞迴實現

快速排序

快排思想:

與歸併排序類似,也使用分治思想,演算法開始選擇一個元素值(第一個或最後一個),作為樞軸,要做的是左邊的元素都小於該基準數(樞軸),右邊的元素都大於該樞軸。
左右子序列的處理方法類似,這樣子問題和原問題處一致,這樣符合分治思路,如用遞迴,我們即可找到當子序列中只有一個元素就是演算法的出口。

演算法流程:

1、i = left, j = right, 將基準數挖出形成第一個坑。
2、從後往前找出比基準數小的數,遇到比它大的數j--,找到後挖出次數arr[j],填到arr[i]中;
3、從前往後找出比基準數大的數,遇到比它小的數i++, 找到後挖出此數arr[i],填到arr[j]中;
4、重複2)3),直到i = j,將基準數填到a[i]。

時間複雜度:

O(nlogn)但若初始序列基本有序時,快速排序反而退化為氣泡排序。

C++示例程式碼

#ifndef QuickSort_hpp
#define QuickSort_hpp

#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;

class QuickSort {
public:
    
    void sort(vector<int>& arr, int len) {
        subSort(arr, 0, len-1);
    }
    
    void subSort(vector<int>& arr, int left, int right) {
        if (left >= right) {
            return;
        }
        int q = partion(arr, left, right);
        subSort(arr, 0 , q-1);
        subSort(arr, q+1, right);
    }
    
    int partion(vector<int>& arr, int left, int right) {
        int pivot = arr[left];//選定最左邊的元素為分割元素
        int i = left;//初始化右移指標【最左元素】
        int j = right;//初始化左移移指標【最右元素】
        while(i < j){
            //從右往左找第一個小於pivot的數
            while (i < j && arr[j] >= pivot) {
                j--;
            }
            //把這個小於pivot的數放到左半部分的一個位置
            if(i < j){
                arr[i] = arr[j];
            }
            
            //從左邊往右邊著第一個大於pivot的數
            while (i < j && arr[i] < pivot) {
                i++;
            }
            //把這個大於pivot的數放到右半部分的一個位置
            if (i < j) {
                arr[j] = arr[i];
            }
        }
        if(i == j){
            arr[i] = pivot;
            cout << "pivot index : "  << j << endl;
        }
        
        return j;
    }
};

#endif /* QuickSort_hpp */

/*QuickSort.cpp*/

#include "QuickSort.hpp"

/*main*/

#include <iostream>
#include <vector>
#include "QuickSort.hpp"

using namespace std;
int main(int argc, const char * argv[]) {
    vector<int> arr6 = {7, 5, 3, 2, 4, 9, 1, 8, 0, 6};
    cout << "arr6: " << endl;
    for (int item : arr6) {
        cout << item <<" ";
    }
    cout << endl;
    QuickSort quickSort = QuickSort();
    quickSort.sort(arr6, int(arr6.size()));
    cout << "quick sort arr6: " << endl;
       for (int item : arr6) {
           cout << item <<" ";
       }
       cout << endl;
    return 0;
}

控制檯輸出,可以看到每次遞迴選擇的pivoit在陣列中被調整的位置

arr6: 
7 5 3 2 4 9 1 1 8 0 6 
pivot index : 8
pivot index : 7
pivot index : 1
pivot index : 4
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 6
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 3
pivot index : 0
pivot index : 1
pivot index : 4
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 9
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 3
pivot index : 0
pivot index : 1
pivot index : 4
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 5
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 3
pivot index : 0
pivot index : 1
pivot index : 6
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 3
pivot index : 0
pivot index : 1
pivot index : 4
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 7
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 3
pivot index : 0
pivot index : 1
pivot index : 4
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 5
pivot index : 0
pivot index : 1
pivot index : 2
pivot index : 0
pivot index : 3
pivot index : 0
pivot index : 1
quick sort arr6: 
0 1 1 2 3 4 5 6 7 8 9 
Program ended with exit code: 0