• <td id="ae6ms"><li id="ae6ms"></li></td>
  • <xmp id="ae6ms"><td id="ae6ms"></td><table id="ae6ms"></table>
  • <table id="ae6ms"></table>
  • <td id="ae6ms"></td>
    <td id="ae6ms"></td>
  • <table id="ae6ms"></table><table id="ae6ms"><td id="ae6ms"></td></table>
  • <td id="ae6ms"></td>
  • <table id="ae6ms"><li id="ae6ms"></li></table>
  • <table id="ae6ms"></table>
    西西軟件園多重安全檢測下載網站、值得信賴的軟件下載站!
    軟件
    軟件
    文章
    搜索

    首頁編程開發VC|VC++ → C++ 基本算法 冒泡法、交換法、選擇法、(實現代碼)大集合

    C++ 基本算法 冒泡法、交換法、選擇法、(實現代碼)大集合

    相關軟件相關文章發表評論 來源:本站原創時間:2010/11/11 10:06:00字體大?。?em class="fontsize">A-A+

    作者:不詳點擊:1215次評論:0次標簽: C++排序算法

    迅雷7v7.9.44.5056 官方最新版
    • 類型:下載工具大?。?i>40.0M語言:中文 評分:9.7
    • 標簽:
    立即下載

    大家在學習C語言的時候,老師可能都會講的幾個算法。

     

    1.冒泡法:


    這是最原始,也是眾所周知的最慢的算法了。
    他的名字的由來因為它的工作看來象是冒泡:
    #include <iostream.h> void BubbleSort(int* pData,int Count) { int iTemp; for(int i=1;i<Count;i++) { for(int j=Count-1;j>=i;j--) { if(pData[j]<pData[j-1]) { iTemp = pData[j-1]; pData[j-1] = pData[j]; pData[j] = iTemp; } } } } void main() { int data[] = {10,9,8,7,6,5,4}; BubbleSort(data,7); for (int i=0;i<7;i++) cout<<data<<" "; cout<<"\n"; } 倒序(最糟情況)
    第一輪:10,9,8,7->10,9,7,8->10,7,9,8->7,10,9,8(交換3次)
    第二輪:7,10,9,8->7,10,8,9->7,8,10,9(交換2次)
    第一輪:7,8,10,9->7,8,9,10(交換1次)
    循環次數:6次交換次數:6次
    其他:第一輪:8,10,7,9->8,10,7,9->8,7,10,9->7,8,10,9(交換2次)
    第二輪:7,8,10,9->7,8,10,9->7,8,10,9(交換0次)
    第一輪:7,8,10,9->7,8,9,10(交換1次) 循環次數:6次交換次數:3次 上面我們給出了程序段,
    現在我們分析它:這里,影響我們算法性能的主要部分是循環和交換,顯然,次數越多,性能就越差。
    從上面的程序我們可以看出循環的次數是固定的,為1+2+...+n-1。寫成公式就是1/2*(n-1)*n。
    現在注意,我們給出O方法的定義: 若存在一常量K和起點n0,使當n>=n0時,有f(n)<=K*g(n),則f(n) = O(g(n))。
    現在我們來看1/2*(n-1)*n,當K=1/2,n0=1,g(n)=n*n時,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)=O(g(n))=O(n*n)。
    所以我們程序循環的復雜度為O(n*n)。 再看交換。從程序后面所跟的表可以看到,兩種情況的循環相同,交換不同。
    其實交換本身同數據源的有序程度有極大的關系,當數據處于倒序的情況時,交換次數同循環一樣(每次循環判斷都會交換),復雜度為O(n*n)。
    當數據為正序,將不會有交換。復雜度為O(0)。亂序時處于中間狀態。正是由于這樣的原因,我們通常都是通過循環次數來對比算法。


    2.交換法:


    交換法的程序最清晰簡單,每次用當前的元素一一的同其后的元素比較并交換。
    #include <iostream.h>
    void ExchangeSort(int* pData,int Count)
    {
    int iTemp;
    for(int i=0;i<Count-1;i++)
    {
    for(int j=i+1;j<Count;j++)
    {
    if(pData[j]<pData)
    {
    iTemp = pData;
    pData = pData[j];
    pData[j] = iTemp;
    }
    }
    }
    }

    void main()
    {
    int data[] = {10,9,8,7,6,5,4};
    ExchangeSort(data,7);
    for (int i=0;i<7;i++)
    cout<<data<<" ";
    cout<<"\n";
    }
    倒序(最糟情況)
    第一輪:10,9,8,7->9,10,8,7->8,10,9,7->7,10,9,8(交換3次)
    第二輪:7,10,9,8->7,9,10,8->7,8,10,9(交換2次)
    第一輪:7,8,10,9->7,8,9,10(交換1次)
    循環次數:6次
    交換次數:6次

    其他:
    第一輪:8,10,7,9->8,10,7,9->7,10,8,9->7,10,8,9(交換1次)
    第二輪:7,10,8,9->7,8,10,9->7,8,10,9(交換1次)
    第一輪:7,8,10,9->7,8,9,10(交換1次)
    循環次數:6次
    交換次數:3次

    從運行的表格來看,交換幾乎和冒泡一樣糟。事實確實如此。循環次數和冒泡一樣也是1/2*(n-1)*n,所以算法的復雜度仍然是O(n*n)。由于我們無法給出所有的情況,所以只能直接告訴大家他們在交換上面也是一樣的糟糕(在某些情況下稍好,在某些情況下稍差)。p#副標題#e#


    3.選擇法:


    現在我們終于可以看到一點希望:選擇法,這種方法提高了一點性能(某些情況下)這種方法類似我們人為的排序習慣:從數據中選擇最小的同第一個值交換,在從省下的部分中選擇最小的與第二個交換,這樣往復下去。
    #include <iostream.h>
    void SelectSort(int* pData,int Count)
    {
    int iTemp;
    int iPos;
    for(int i=0;i<Count-1;i++)
    {
    iTemp = pData;
    iPos = i;
    for(int j=i+1;j<Count;j++)
    {
    if(pData[j]<iTemp)
    {
    iTemp = pData[j];
    iPos = j;
    }
    }
    pData[iPos] = pData;
    pData = iTemp;
    }
    }

    void main()
    {
    int data[] = {10,9,8,7,6,5,4};
    SelectSort(data,7);
    for (int i=0;i<7;i++)
    cout<<data<<" ";
    cout<<"\n";
    }


    倒序(最糟情況)


    第一輪:10,9,8,7->(iTemp=9)10,9,8,7->(iTemp=8)10,9,8,7->(iTemp=7)7,9,8,10(交換1次)
    第二輪:7,9,8,10->7,9,8,10(iTemp=8)->(iTemp=8)7,8,9,10(交換1次)
    第一輪:7,8,9,10->(iTemp=9)7,8,9,10(交換0次)
    循環次數:6次
    交換次數:2次


    其他:


    第一輪:8,10,7,9->(iTemp=8)8,10,7,9->(iTemp=7)8,10,7,9->(iTemp=7)7,10,8,9(交換1次)
    第二輪:7,10,8,9->(iTemp=8)7,10,8,9->(iTemp=8)7,8,10,9(交換1次)
    第一輪:7,8,10,9->(iTemp=9)7,8,9,10(交換1次)
    循環次數:6次
    交換次數:3次
    遺憾的是算法需要的循環次數依然是1/2*(n-1)*n。所以算法復雜度為O(n*n)。
    我們來看他的交換。由于每次外層循環只產生一次交換(只有一個最小值)。所以f(n)<=n
    所以我們有f(n)=O(n)。所以,在數據較亂的時候,可以減少一定的交換次數。4.插入法:
    插入法較為復雜,它的基本工作原理是抽出牌,在前面的牌中尋找相應的位置插入,然后繼續下一張
    #include <iostream.h>
    void InsertSort(int* pData,int Count)
    {
    int iTemp;
    int iPos;
    for(int i=1;i<Count;i++)
    {
    iTemp = pData;
    iPos = i-1;
    while((iPos>=0) && (iTemp<pData[iPos]))
    {
    pData[iPos+1] = pData[iPos];
    iPos--;
    }
    pData[iPos+1] = iTemp;
    }
    }


    void main()
    {
    int data[] = {10,9,8,7,6,5,4};
    InsertSort(data,7);
    for (int i=0;i<7;i++)
    cout<<data<<" ";
    cout<<"\n";
    }

    倒序(最糟情況)
    第一輪:10,9,8,7->9,10,8,7(交換1次)(循環1次)
    第二輪:9,10,8,7->8,9,10,7(交換1次)(循環2次)
    第一輪:8,9,10,7->7,8,9,10(交換1次)(循環3次)
    循環次數:6次
    交換次數:3次

    其他:
    第一輪:8,10,7,9->8,10,7,9(交換0次)(循環1次)
    第二輪:8,10,7,9->7,8,10,9(交換1次)(循環2次)
    第一輪:7,8,10,9->7,8,9,10(交換1次)(循環1次)
    循環次數:4次
    交換次數:2次

    上面結尾的行為分析事實上造成了一種假象,讓我們認為這種算法是簡單算法中最好的,其實不是,因為其循環次數雖然并不固定,我們仍可以使用O方法。從上面的結果可以看出,循環的次數f(n)<=1/2*n*(n-1)<=1/2*n*n。所以其復雜度仍為O(n*n)(這里說明一下,其實如果不是為了展示這些簡單排序的不同,交換次數仍然可以這樣推導)?,F在看交換,從外觀上看,交換次數是O(n)(推導類似選擇法),但我們每次要進行與內層循環相同次數的‘=’操作。正常的一次交換我們需要三次‘=’而這里顯然多了一些,所以我們浪費了時間。最終,我個人認為,在簡單排序算法中,選擇法是最好的。插入排序
    #include <iostream>
    using namespace std;

    void coutstream(int a[],int n){
    for(int i=0;i!=n;i++)
    cout<<a<<" ";
    }

    void insertsort(int a[],int n){
    int temp;
    for(int i=1;i<n;i++)
    {
    int j=i;
    temp=a; //先把a位置的數據存起來
    while(j>0&&temp<a[j-1])
    {
    a[j]=a[j-1];
    j--;
    }
    a[j]=temp;
    }
    }


    int main()
    {
    int a[5]={1,6,4,8,4};
    insertsort(a,5);//插入排序
    coutstream(a,5);//
    return 0;
    }


    二、高級排序算法:


    高級排序算法中我們將只介紹這一種,同時也是目前我所知道(我看過的資料中)的最快的。它的工作看起來仍然象一個二叉樹。首先我們選擇一個中間值middle程序中我們使用數組中間值,然后把比它小的放在左邊,大的放在右邊(具體的實現是從兩邊找,找到一對后交換)。然后對兩邊分別使用這個過程(最容易的方法——遞歸)。
    1.快速排序:
    #include <iostream.h>

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

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

    void QuickSort(int* pData,int Count)
    {
    run(pData,0,Count-1);
    }

    void main()
    {
    int data[] = {10,9,8,7,6,5,4};
    QuickSort(data,7);
    for (int i=0;i<7;i++)
    cout<<data<<" ";
    cout<<"\n";
    }

    這里我沒有給出行為的分析,因為這個很簡單,我們直接來分析算法:首先我們考慮最理想的情況
    1.數組的大小是2的冪,這樣分下去始終可以被2整除。假設為2的k次方,即k=log2(n)。
    2.每次我們選擇的值剛好是中間值,這樣,數組才可以被等分。
    第一層遞歸,循環n次,第二層循環2*(n/2)......
    所以共有n+2(n/2)+4(n/4)+...+n*(n/n) = n+n+n+...+n=k*n=log2(n)*n
    所以算法復雜度為O(log2(n)其他的情況只會比這種情況差,最差的情況是每次選擇到的middle都是最小值或最大值,那么他將變成交換法(由于使用了遞歸,情況更糟)。但是你認為這種情況發生的幾率有多大??呵呵,你完全不必擔心這個問題。實踐證明,大多數的情況,快速排序總是最好的。如果你擔心這個問題,你可以使用堆排序,這是一種穩定的O(log2(n)*n)算法,但是通常情況下速度要慢于快速排序(因為要重組堆)

    三、其他排序


    1.雙向冒泡:
    通常的冒泡是單向的,而這里是雙向的,也就是說還要進行反向的工作。
    代碼看起來復雜,仔細理一下就明白了,是一個來回震蕩的方式。
    寫這段代碼的作者認為這樣可以在冒泡的基礎上減少一些交換(我不這么認為,也許我錯了)。
    反正我認為這是一段有趣的代碼,值得一看。
    #include <iostream.h>
    void Bubble2Sort(int* pData,int Count)
    {
    int iTemp;
    int left = 1;
    int right =Count -1;
    int t;
    do
    {
    //正向的部分
    for(int i=right;i>=left;i--)
    {
    if(pData<pData[i-1])
    {
    iTemp = pData;
    pData = pData[i-1];
    pData[i-1] = iTemp;
    t = i;
    }
    }
    left = t+1;

    //反向的部分
    for(i=left;i<right+1;i++)
    {
    if(pData<pData[i-1])
    {
    iTemp = pData;
    pData = pData[i-1];
    pData[i-1] = iTemp;
    t = i;
    }
    }
    right = t-1;
    }while(left<=right);
    }

    void main()
    {
    int data[] = {10,9,8,7,6,5,4};
    Bubble2Sort(data,7);
    for (int i=0;i<7;i++)
    cout<<data<<" ";
    cout<<"\n";
    }

    快速排序
    #include <iostream>
    using namespace std;
    class QuickSort
    {
    public:
    void quick_sort(int* x,int low,int high)
    {
    int pivotkey;
    if(low <high)
    {
    pivotkey=partion(x,low,high);
    quick_sort(x,low,pivotkey-1);
    quick_sort(x,pivotkey+1,high);
    }
    }
    int partion(int* x,int low,int high)
    {
    int pivotkey;
    pivotkey=x[low];
    while(low <high)
    {
    while (low <high&&x[high]>=pivotkey)
    --high; //還有while循環只執行這一句
    x[low]=x[high];
    while (low <high&&x[low] <=pivotkey)
    ++low; //還有while循環只執行這一句
    x[high]=x[low];
    }
    x[low]=pivotkey;
    return low;
    }
    };
    int main()
    {
    int x[10]={52,49,80,36,14,58,61,97,23,65};
    QuickSort qs;
    qs.quick_sort(x,0,9);
    cout <<"排好序的數字序列為:" <<endl;
    for (int i=0;i <10;i++)
    {
    printf("%d ",x);
    }
    return 0;
    }

    2.SHELL排序


    這個排序非常復雜,看了程序就知道了。
    首先需要一個遞減的步長,這里我們使用的是9、5、3、1(最后的步長必須是1)。
    工作原理是首先對相隔9-1個元素的所有內容排序,然后再使用同樣的方法對相隔5-1個元素的排序以次類推。
    #include <iostream.h>
    void ShellSort(int* pData,int Count)
    {
    int step[4];
    step[0] = 9;
    step[1] = 5;
    step[2] = 3;
    step[3] = 1;

    int iTemp;
    int k,s,w;
    for(int i=0;i<4;i++)
    {
    k = step;
    s = -k;
    for(int j=k;j<Count;j++)
    {
    iTemp = pData[j];
    w = j-k;//求上step個元素的下標
    if(s ==0)
    {
    s = -k;
    s++;
    pData[s] = iTemp;
    }
    while((iTemp<pData[w]) && (w>=0) && (w<=Count))
    {
    pData[w+k] = pData[w];
    w = w-k;
    }
    pData[w+k] = iTemp;
    }
    }
    }

    void main()
    {
    int data[] = {10,9,8,7,6,5,4,3,2,1,-10,-1};
    ShellSort(data,12);
    for (int i=0;i<12;i++)
    cout<<data<<" ";
    cout<<"\n";
    }
    程序看起來有些頭疼。不過也不是很難,把s==0的塊去掉就輕松多了,這里是避免使用0步長造成程序異常而寫的代碼。這個代碼很值得一看。這個算法的得名是因為其發明者的名字D.L.SHELL。依照參考資料上的說法:“由于復雜的數學原因避免使用2的冪次步長,它能降低算法效率?!绷硗馑惴ǖ膹碗s度為n的1.2次冪。同樣因為非常復雜并“超出本書討論范圍”的原因(我也不知道過程),我們只有結果。冒泡排序性能優化版#include <iostream>
    using namespace std;
    void maopao(int *list,int n)
    {
    int i=n,j,temp;
    bool exchange;//當數據已經排好時,退出循環
    for(i=0;i<n;i++)
    {
    exchange=false;
    for (j=0;j<n-i-1;j++)
    {
    if (list[j]>list[j+1])
    {
    temp=list[j];
    list[j]=list[j+1];
    list[j+1]=temp;
    exchange=true;
    }

    }
    if (!exchange)
    {
    return;
    }
    }
    }
    int main()
    {
    int a[7]={32,43,22,52,2,10,30};
    maopao(a,7);
    for(int i=0;i<7;i++)
    cout<<a<<" ";
    return 0;
    }

      迅雷離線
      (11)迅雷離線
      西西軟件園提供好用的迅雷離線下載,開電腦根本下不完,離線的意思是說你關機走了,迅雷那邊的服務器還在幫你下載,但不是下到你的電腦上,而是下在他自己的服務器上,等你再上自己電腦的時候就能用非常非??斓乃俣戎苯訌乃姆⻊掌魃习涯莻源下載下來了。迅雷離線下載可以瀏覽并將自己喜愛的內容保存到離線空間或者移動設備上,您可以使用視頻加速功能在線播放或下載到本地播放,離線空間的片源,可以使用云點播功能直接播放,免...更多>>
      • 極速迅雷v1.0.35.366 官方最新版

        11-27 / 22.7M

        推薦理由:談到下載利器,大家熟悉的有迅雷、QQ旋風。論到資源數量時,還是迅雷優先。但是對于普通用戶來說,迅雷捆綁
      • 迅雷7v7.9.44.5056 官方最新版

        02-14 / 40.0M

        推薦理由:迅雷7擁有國內80%以上的用戶使用的下載工具。使用迅雷7官方下載,要注意它在后臺自動上傳文件,P2P的都會這
      • 手機迅雷Android版V5.32.2.4620 官

        01-16 / 28.1M

        推薦理由:國慶長假,想好去哪里玩了沒?路上很無聊咋辦?趕緊使用手機迅雷,隨時下、隨心享,不僅能在線觀看,還能一
      • 手機迅雷 for iPhone5.13 官方最新

        06-13 / 61.4M

        推薦理由:經過4月初發布的第一個beta公測版,我們發現了自己的優勢,同樣也看見了本身的不足。所以我們近期對該版本軟
      • 迅雷離線批量添加BT種子工具

        12-19 / 108KB

        推薦理由:迅雷離線批量添加BT種子工具可以批量添加bt種子到迅雷離線空間,這樣可以省去種子一個個添加的麻煩,節約時
      • 迅雷離線2.3.3.1 安卓版

        07-29 / 8.0M

        推薦理由:長久以來, 離線下載作為迅雷客戶端下載的增值服務, 以其解決冷門下載慢、死鏈無法下、P2P封鎖突破以及加速等
      bt下載軟件
      (21)bt下載軟件
      西西軟件園提供好用的下載軟件免費下載,下載是目前非常流行的一種下載方式,一般我們下載文件或軟件,大都由站點或站臺下載,若同時間下載人數多時,基于該服務器頻寬的因素,速度會減慢許多,而下載軟件卻恰巧相反,同時間下載的人數越多你下載的速度便越快,因為它采用了多點對多點的傳輸原理。...更多>>
      迅雷8
      (14)迅雷8
      迅雷.正式版發布,在舊版的基礎上,迅雷優化了主界面,增加了一些自定義皮膚。大大增強了下載功能,兼容了更多的下載格式,西西軟件園為您提供迅雷.官方下載版本和去除會員限制版本迅雷.改進迅雷.改進了項目管理策略。簡單的說,迅雷.中所有的功能改進,都將獨立開發測試,只要某項目能夠在版本指定的時間段內準備就緒,就能夠整合至當前版本發布。若不能將延期至下一版本。這樣就避免了迅雷.為了等待某項目解決問題,從而使整體發...更多>>
      下載工具排行
      (282)下載工具排行
      下載工具哪個好呢,下載工具軟件排行榜出來了。第一非迅雷莫屬,雖然咋雷現在越來越大了,下載速度也不給力了需要會員啦,還有偷偷上傳數據。不過相比其他下載工具還是給力些了。只要自己限制迅雷上傳速度就可以用了。還有就是現在瀏覽器都自帶有自家的下載工具,速度都很給力了哦。瀏覽器搜狗瀏覽器谷歌瀏覽器都很給力哦。第二送給旋風吧,畢竟用戶群太大了,好多朋友喜歡旋風升級的。...更多>>
      • 迅雷7v7.9.44.5056 官方最新版

        02-14 / 40.0M

        推薦理由:迅雷7擁有國內80%以上的用戶使用的下載工具。使用迅雷7官方下載,要注意它在后臺自動上傳文件,P2P的都會這
      • QQ旋風20154.8.773.400 官方正式版

        11-20 / 9.3M

        推薦理由:QQ旋風是騰訊推出的基于P2P技術的下載工具,支持HTTP、BT、Emule等下載協議,同時,支持更大的免費離線下載
      • 西西軟件盒v3.0.0.0 正式版

        05-15 / 2M

        推薦理由:西西軟件盒是由 《西西軟件園》 http://www.pirinnaturalssoapandspa.com/   打造的一款集 下載、更新、卸載 為一體的軟件
      • 快車(FlashGet)3.7.0.1223 官方正式

        05-15 / 7.3M

        推薦理由:快車(FlashGet)-全球最多人使用的下載工具。能高速、安全、便捷地下載電影、音樂、游戲、視頻、軟件、圖
      • 電驢VeryCDV1.2.2 正式官方版

        05-15 / 4.1M

        推薦理由:VeryCD電驢(easyMule)是在eMule的基礎上全新開發的新版本,具有更快的下載和上傳速度,更簡便的操作界面,以
      • 極速迅雷v1.0.35.366 官方最新版

        11-27 / 22.7M

        推薦理由:談到下載利器,大家熟悉的有迅雷、QQ旋風。論到資源數量時,還是迅雷優先。但是對于普通用戶來說,迅雷捆綁
      迅雷極速版
      (22)迅雷極速版
      迅雷是一款超的下載工具,可以支持所有的協議,包括,,,等。多資源超線程技術還具有互聯網下載負載均衡功能,在不降低用戶體驗的前提下,迅雷網絡可以對服務器資源進行均衡,有效降低了服務器負載。世界上最快的下載引擎再一次提速,億用戶的選擇,迅雷最懂下載用戶,據悉版的開發團隊放棄了精簡版本,全新開始打造的極速版,不僅優化升級了下載速度,界面布局也進行了全新改版,讓用戶可以舒心地享受迅雷極速下載體驗。此外最大特...更多>>

      相關評論

      閱讀本文后您有什么感想? 已有人給出評價!

      • 8 喜歡喜歡
      • 3 頂
      • 1 難過難過
      • 5 囧
      • 3 圍觀圍觀
      • 2 無聊無聊

      熱門評論

      最新評論

      發表評論 查看所有評論(0)

      昵稱:
      表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
      字數: 0/500 (您的評論需要經過審核才能顯示)
      女人让男人桶30分钟免费视频,女人张开腿让男人桶个爽,一进一出又大又粗爽视频
    • <td id="ae6ms"><li id="ae6ms"></li></td>
    • <xmp id="ae6ms"><td id="ae6ms"></td><table id="ae6ms"></table>
    • <table id="ae6ms"></table>
    • <td id="ae6ms"></td>
      <td id="ae6ms"></td>
    • <table id="ae6ms"></table><table id="ae6ms"><td id="ae6ms"></td></table>
    • <td id="ae6ms"></td>
    • <table id="ae6ms"><li id="ae6ms"></li></table>
    • <table id="ae6ms"></table>