快速排序

快速排序:使用的是分治思想 (歸併排序也是);ios

(1)選一個元素M做爲基準數。算法

(2)把小於等於M的元素放在數組的左邊,大於M的元素放在數組右邊;這是M的位置已經是正確的,再也不改變。數組

(3)對M左邊、右邊的的數組分別使用(1)(2),知道數組中只有一個元素。dom

性能:ide

最壞時間複雜度是O(n2),平均時間複雜度是(nlogn),最好時間複雜度是(nlogn),是一種不穩定排序。函數

快速排序的三步分治過程:分解,解決,合併。因爲子數組是原址排序,因此不須要合併操做。性能

注:在代碼中,p r 均是數組下標,p 是首元素的下標, r 是最後一個元素的下標測試

QuickSort( A, p, r)ui

     if   p < r spa

         q = Partition( A, p, r ) 

         QuickSort( A, p, q-1)

         QuickSort( A, q+1, r)

算法的關鍵是 Partition 過程,他實現了對子數組 A[p, r] 的原址重排

Partition ( A, p, r ) 

      x = A[ r ]

      i = p - 1

      for  j  =  p  to  r -1

            if  A[ j ]  <=  x

                i = i + 1 

               exchange A[ i ]  with A[ j] 

     exchange A[ i+1] with A[ r ]

     return i + 1

快速排序的隨機化版本(使得算法對全部的輸入都有較好的指望性能),新的劃分程序中,只在真正進行劃分前進行一次交換,QuickSort( A, p, r)代碼不變;

RandomPartition( A, p, r)

         i = Random(p, r)

        exchance A[ r ]  with A[ i ]

        return Partition( A, p, r)

代碼:

#include<iostream>
#include<vector>
using namespace std;
template<class T>
int Partition(vector<T>&A, int p, int r)    // p 和 r 均爲數組段的下標,p是數組首元素下標,r是數組最後一個元素下標
{
    T x = A[r];
    int  flag = p - 1;
    for (int j = p; j <= r-1; j++)    //遍歷數組中的元素
    {
        if (A[j] <= x)                // 將數組中小於 A[r]的元素移到數組的左邊
        {
            flag = flag + 1;
            T temp = A[flag];
            A[flag] = A[j];
            A[j] = temp;
        }
    }
    T tem = A[flag + 1];
    A[flag + 1] = A[r];
    A[r] = tem;
    return flag + 1;
}
template<class T>
void QuickSort(vector<T>& Arry,int p,int r)
{
    if (p <= r-1)
    {
        int q = Partition(Arry,p,r); //返回的元素位置已經被正確分類,即下面函數參數有 q-1,q+1,
        for (int i = 0; i <= r; i++)
            cout << Arry[i] << " ";
        cout << endl;
        QuickSort(Arry,p,q-1);         //這裏也是分治的思想,q位置的元素位置已正確,只需對(q,q-1)與(q+1,r)排序
        QuickSort(Arry, q+1,r);
    }
}

測試代碼:

int main()
{
    vector<int> arry= { 210, 12,19, 4, 7, 10, 15,21, 41, 51, 61, 81, 71, 91, 100,310,250,630,0,17};
    for (int i = 0; i < 20; i++)
        cout << arry[i] << " ";
    cout << endl;
    QuickSort<int>(arry, 0, 19);
    for (int i = 0; i < 20; i++)
        cout << arry[i] << " ";
    cout << endl;
    cout << "BigThink" << endl;
    system("pause");
    return 0;
}
View Code

vector 容器作函數參數:

void Example( vector<int> vec);

void Example( vector<int> *vec);

void Example( const vector<int> * vec);   //在函數內不能改變 vec指向的對象

void Example( vector<int>& vec);

void Example( const  vector<int>& vec);    // 在函數內不能改變 vec 對象

相關文章
相關標籤/搜索