快速選擇

快速選擇和快速排序類似,將數組分爲S1和S2。當K值小於S1的的長度時,對S1進行遞歸。當k值剛好等於pivot時,那麼已經找到了。當k值大於S1長度加一時,對S2進行遞歸。最後K始終在數組下標k-1的位置。

#include <iostream>
#include <vector>
using namespace std;

template <typename Comparable>
void insertionSort(vector<Comparable> &vec,int left ,int right)
{
    for(int p=left+1;p<=right;p++)
    {
        Comparable tmp=std::move(vec[p]);
        int j=p;
        for(;j>left&&tmp<vec[j-1];j--)
            vec[j]=std::move(vec[j-1]);

        vec[j]=std::move(tmp);
    }
}


//三位中值分割
template <typename Comparable>
const Comparable & median3(vector<Comparable> & a,int left,int right)
{
    int center=(left+right)/2;
    if(a[right]<a[left])
        std::swap(a[center], a[left]);
    if (a[right]<a[center])
        std::swap(a[right], a[center]);
    if(a[center]<a[left])
        std::swap(a[center], a[left]);

    std::swap(a[center], a[right-1]);
    return a[right-1];


}
template <typename Comparable>
void quickSelect(vector<Comparable> & a,int left,int right,int k)
{
    if(left+10<=right)  //當數量比較少時,使用插入排序效果較好
    {
        const Comparable & pivot=median3(a, left, right);
        int i=left;
        int j=right-1;

        for(;;)
        {

            while (a[++i]<pivot){}
            while (pivot<a[--j]){}
            if(i<j)
            {
                std::swap(a[i], a[j]);
            }
            else
            {
                break;
            }
        }
        std::swap(a[i], a[right-1]);

        if(k<=i)
        {
            quickSelect(a, left, i-1, k);
        }
        else if (k>i+1)
        {
            quickSelect(a, i+1,right,k);
        }


    }
    else
    {
        insertionSort(a,left,right);

    }

}

template <typename Comparable>
void quickSelect(vector<Comparable> & a,int k)
{
     quickSelect(a,0,a.size()-1,k);
}



int main(int argc, const char * argv[]) {
    // insert code here...
    vector<int> a{1,6,3,5,4,6,7,10,2,37,38,12,2,32,5,36,73,224,7,8,2,4,7,2,7,9,0,4,45,34,67,23,
    47,45,98,27,56};
    int k;
    cin>>k;
    cout<<endl;
    quickSelect(a, k);
    std::cout <<a[k-1]<<endl;
    return 0;
}
發佈了55 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章