快速排序 QuickSort (C++迭代,遞歸)


/*
 * QuickSort.h
 * 快速排序(將每一個元素轉換為軸點元素)
 *  Created on: 2020年2月12日
 *      Author: LuYonglei
 */

#ifndef SRC_QUICKSORT_H_
#define SRC_QUICKSORT_H_
#include <vector>
#include <stack>
#include <cstdlib>
#include <ctime>
using namespace std;

template<typename T>
int compare(const T &left, const T &right) {
    //比較兩個元素大小
    //left > right    return  1
    //left = right    return  0
    //left < right    return -1
    return left > right ? 1 : (left == right ? 0 : -1);
}

template<typename T>
int pivotIndex(vector<T> &arr, int begin, int end) {
    //構造出arr中的軸點元素並返回索引位置
    //為保證盡可能不出現最壞情況,隨機選擇一個begin-end范圍內的元素作為軸點元素
    srand(time(0));
    int randIndex = rand() % (end - begin);
    //把隨機選擇的軸點位置和begin位置交換元素
    swap(arr[begin], arr[begin + randIndex]);
    //備份begin位置的元素
    T pivotValue = arr[begin];
    //end指向最后一個元素
    end--;
    //當begin<end時進行掃描
    while (begin < end) {
        while (begin < end) {
            //先從右往左掃描
            if (-1 == compare(pivotValue, arr[end])) {
                //如果軸點元素小於end位置的元素
                end--;
            } else {
                //軸點元素大於等於end位置元素
                arr[begin] = arr[end];
                begin++;
                break;
            }
        }
        while (begin < end) {
            //從左往右掃描
            if (compare(pivotValue, arr[begin]) == 1) {
                //如果軸點元素大於begin位置的元素
                begin++;
            } else {
                //如果軸點元素小於等於begin位置的元素
                arr[end] = arr[begin];
                end--;
                break;
            }
        }
    }
    //將軸點位置用value覆蓋
    arr[begin] = pivotValue;
    //返回軸點元素位置
    return begin;
}

#if 0
//遞歸實現
template<typename T>
void sort(vector<T> &arr, int begin, int end) {
    //對[begin,end)范圍內的元素進行快速排序
    if ((end - begin) < 2)
        return;
    int pivot = pivotIndex(arr, begin, end);
    sort(arr, begin, pivot);
    sort(arr, pivot + 1, end);
}

#else
//迭代實現
typedef struct _sortPair {
    int begin;
    int end;
} SORT_PAIR;

template<typename T>
void sort(vector<T> &arr, int begin, int end) {
    if ((end - begin) < 2)//元素個數小於2,直接退出
        return;
    stack<SORT_PAIR> s;
    s.push(SORT_PAIR { begin, end });
    int sBegin=0;
    int sEnd=0;
    int pivot=0;
    while (s.size() != 0) {
        sBegin = s.top().begin;
        sEnd = s.top().end;
        pivot = pivotIndex(arr, sBegin, sEnd);//確定軸點元素位置
        s.pop();//彈出棧頂元素
        if ((pivot - sBegin) >= 2) {//元素個數大於等於2,才需要進行排序
            s.push(SORT_PAIR { sBegin, pivot });
        }
        if ((sEnd - pivot - 1 >= 2)) {//元素個數大於等於2才需要進行排序
            s.push(SORT_PAIR { pivot + 1, sEnd });
        }
    }
}

#endif

template<typename T>
void quickSort(vector<T> &arr) {
    sort(arr, 0, arr.size());
}

#endif /* SRC_QUICKSORT_H_ */

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM