如何寫出一個較好的快速排序程式,寫出較好排序程式

來源:互聯網
上載者:User

如何寫出一個較好的快速排序程式,寫出較好排序程式
寫出一個較好的快速排序程式

  • 快速排序是常用的排序演算法之一,但要想寫出一個又快又準的使用程式,就不是那麼簡單了
需要注意的事項
  • 首先要寫正確。通常使用遞迴實現。其遞迴相當於二叉樹展開,因此如果要用迭代實現的話需要使用一個隊列來儲存後續遍曆資訊。
  • 快速排序需要找到一個pivot值,如果順序選擇pivot則易造成N^2的複雜度,如果使用隨機數則效果最好,但開銷又太大,採取三數中值法比較合適。三數中值法指的是選取第一個值,最後一個值,數組中間的值的中值。有文獻表明可以提升5%的已耗用時間。
  • 當數組長度較小時,如10個元素以下,最好使用插入排序或者選擇排序完成,以防止多次函數調用帶來的開銷。而遞迴到底層數組長度總是會變小的,因此這麼做非常有必要。
  • 在合并前後兩部分數組時,採用兩邊夾方法,在前後兩部分各找到一個大於和小於的值再交換。相比通常情況下找到比pivot小的值就進行交換,能提高運行效率。
實現代碼
  • 代碼如下。包括插入排序insert_sort,遞迴函式,三分中值函數三個輔助函數。
  • 三分中值函數其實採用的是插入排序。通過三次比較,確定中值。
  • 插值演算法使用臨時變數tmp避免了大量swap函數調用。
#include<iostream>#include<iomanip>#include<vector>#include<cstdlib>#include<ctime>#include<algorithm>using namespace std;inline void swap(vector<int>& num, int p, int q){    int t = num[p];    num[p] = num[q];    num[q] = t;}void insert_sort(vector<int>& num){    int tmp, j;    for (int i = 1; i < num.size(); i++){        tmp = num[i];        for (j = i - 1; j >= 0 && num[j] > tmp; j--)            num[j + 1] = num[j];        num[j + 1] =tmp;    }}int quick_sort_sub(vector<int>& num, int p, int q){    if (p >= q)        return 0;    // if 4 elements or less, use insert sort    if (p + 10 > q){        vector<int> tnum(num.begin() + p, num.begin() + q + 1);        insert_sort(tnum);        for (int i = 0; i < tnum.size(); i++)            num[p + i] = tnum[i];    }    int idx = quick_three_partition(num, p, q);    swap(num, idx, q);    int pivot = num[q];    int left = p, right = q - 1;    while (1){        while (num[left] < pivot)            ++left;        while (num[right] >= pivot)            --right;        if (left < right)            swap(num, left, right);        else            break;    }    swap(num, left, q);    quick_sort_sub(num, p, left - 1);    quick_sort_sub(num, left + 1, q);    return left;}void quick_sort(vector<int>& num){    quick_sort_sub(num, 0, num.size() - 1);}int main(){    const int n = 10;    /*int num_array[n]= {2,1};    vector<int> num(num_array, num_array + n);*/    srand( time(NULL) );    vector<int> num(n);    for (auto& e : num)        e = rand() % n;    quick_sort(num);    for (auto& e : num)        cout << setw(4) << e << ' ';    cout << endl;    cout << "vector is sorted? : " << is_sorted(num.begin(), num.end()) << endl;    return 0;}

 
 

轉載請註明作者:Focustc,部落格地址為http://blog.csdn.net/caozhk,原文連結為點擊開啟
跪一彙編 寫個排序的程式

3.5快速排序

Tony Hoare在1962年首次提出了快速排序演算法。對快速排序方法的研究表明,至今快速排序演算法仍然是流傳久遠的最實用的排序演算法。只在輸入資料項目有更詳細的資訊時,其它排序演算法才可能勝過快速排序演算法。快速排序演算法是利用分治技術的典型例子,隨機分治策略是設計組合最佳化與計算幾何一類問題有效演算法的基礎。分治策略分為三步:

(1)將問題分成若干大小基本相等的子問題;

(2)獨立地解決這些子問題;

(3)將子問題歸併成原問題的解。

快速排序的基本思路是:首先我們選擇一個中間值middle(程式中我們可使用數組中間值),把比中間值小的放在其左邊,比中間值大的放在其右邊。由於這個排序演算法較複雜,我們先給出其進行一次排序的程式架構(從各類資料結構教材中可得):
void QuickSort(int *pData, int left, int right)
{
int i, j;
int middle, iTemp;
i = left;
j = right;

middle = pData[(left + right) / 2]; //求中間值
do
{
while ((pData[i] < middle) && (i < right)) //從左掃描大於中值的數
i++;
while ((pData[j] > middle) && (j > left)) //從右掃描小於中值的數
j--;
if (i <= j) //找到了一對值
{
//交換
iTemp = pData[i];
pData[i] = pData[j];
pData[j] = iTemp;
i++;
j--;
}
} while (i <= j) ; //如果兩邊掃描的下標交錯,就停止(完成一次)

//當左邊部分有值(left<j),遞迴左半邊

if(left<j)
QuickSort (pData,left,j);
//當右邊部分有值(right>i),遞迴右半邊
if(right>i)
QuickSort (pData,i,right);
}

由此可見,上述排序演算法中採用了遞迴策略。我們根據上述函數,重新書寫一個與我們應用程式架構相符的函數,可動態在對話方塊客戶區顯示變化過程:
void QuickSort(int objectName[], CDC &dc, int left, int right)
{
int i, j;
int middle, iTemp;
i = left;
j = right;

middle = sortObject[objectName[(left+right)/2]].iNumber; //求中間值
do
{
while ((sortObject[objectName[i]].iNumber < middle) && ( i < right))
//從左掃描大於中值的數
i++;
while ((sortObject[objectName[j]].iNumber > middle)&&(j > left))
......餘下全文>>
 
我想寫一個用C++編寫快速排序的程式,是從大到小排的,知道儘快寫給我,哦

/*
快排麼。網上一搜就一堆了。演算法只是一種思想或說成一種方法而已,並非就C語言。其它語言也一樣
快排也有點像二路歸併:從一個無序的序列中隨機取出一個值q做為支點,然後把大於q的放到一邊,小於q的放到q的另一邊,然後再以q為分界點,分別對q的兩邊
進行排序(快排時直接再對q兩邊重新取支點,整理,再取支點,...直到支點兩旁都有序。也就是支點兩旁只有一個數時)
*/
#include <stdio.h>
#include <stdlib.h>
int Qsort(int p[],int beg,int end)
{
if(beg+1>=end)return 0;//退出遞迴
int low,hight,q;
low=beg;
hight=end;
q=p[low];//q為支點,其實q可以為隨機數。但相應以下程式就要改了
while(1){
while(low<hight && p[hight]>q)hight--;
if(low>=hight)break;
p[low++]=p[hight];
while(low<hight && p[low]<q)low++;
p[hight++]=p[low];
}
p[low]=q;
Qsort(p,beg,low-1);
Qsort(p,low+1,end);
}
int main()
{
int i,a[]={1,32,6,4,54,654,6,6,2,76,76,7,66,5,544,334,34,78};
Qsort(a,0,sizeof(a)/4-1);
for(i=0;i<sizeof(a)/4;i++)printf(" %d ",a[i]);
system("pause");
return 0;
}
快速排序的優勢和支點元素的選擇有關係。
所選支點元素每次遞迴後都在最前面或最後面。這樣情況就會最差了。
我們知道一般的排序。(如冒泡。。)在一個數組p[m,n]中排序。都是確定最大或最小,而確定最大值(最小值)要經過n-m-1次比較。
而整個過程就差不多是(n-m-1)!次比較。
快排中:一次比較可以確定支點元素的位置。若p[m,q,n](q為支點元素)。當然確定第一個元素也是要比較(n-m-1)次。但第二個,第三個(第二層)就是(q-m-1)和(n-q-1)次比較。
明顯q的值若為m或n,快排就沒有什麼優勢了

看了LS的回答,還是我水平最高嘛……喔厚厚厚……希望採納!鞠躬……
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.