算法與數(shù)據(jù)結(jié)構(gòu)(七):快速排序

在上一篇中再愈,回顧了一下針對(duì)選擇排序的優(yōu)化算法——堆排序。堆排序的時(shí)間復(fù)雜度為O(nlogn)馋艺,而快速排序的時(shí)間復(fù)雜度也是O(nlogn)侧纯。但是快速排序在同為O(n*logn)的排序算法中,效率也是相對(duì)較高的碍讨,而且快速排序使用了算法中一個(gè)十分經(jīng)典的思想——分治法治力;因此掌握快速排序還是很有必要的。

快速排序的基本思想如下:

  1. 在一組無序元素中勃黍,找到一個(gè)數(shù)作為基準(zhǔn)數(shù)宵统。
  2. 將大于它的數(shù)全部移動(dòng)到它的右側(cè),小于它的全部移動(dòng)到右側(cè)覆获。
  3. 在分成的兩個(gè)區(qū)中马澈,再次重復(fù)1到2 的步驟,直到所有的數(shù)全部有序

下面還是來看一個(gè)例子
[3,6,1,2,8,4,7]
首先選取一個(gè)基準(zhǔn)數(shù)弄息,一般選擇序列最左側(cè)的數(shù)為基準(zhǔn)數(shù)痊班,也就是3,將小于3的數(shù)移動(dòng)到3的左邊摹量,大于3的移動(dòng)到3的右邊涤伐,得到如下的序列
[2,1,3,6,8,4,7]
接著針對(duì)左側(cè)的[2, 1] 這個(gè)序列和 [6, 8, ,4, 7]這兩個(gè)序列再次執(zhí)行這種操作,直到所有的數(shù)都變?yōu)橛行驗(yàn)橹埂?/p>

知道了具體的思路下面就是寫算法了缨称。

void QSort(int a[], int n)
{
    int nIdx = adjust(a, 0, n -1);

    //針對(duì)調(diào)整之后的數(shù)據(jù)左右兩側(cè)序列都再次進(jìn)行調(diào)整
    if(nIdx != -1)
    {
        QSort(&a[0], nIdx);
        QSort(&a[nIdx + 1], n - nIdx - 1);
    }
}

這里定義了一個(gè)函數(shù)作為快速排序的函數(shù)凝果,函數(shù)需要傳入序列的首地址以及序列中間元素的長(zhǎng)度。在排序函數(shù)中只需要關(guān)注如何進(jìn)行調(diào)整即可睦尽。

這里進(jìn)行了一個(gè)判斷器净,當(dāng)調(diào)整函數(shù)返回-1時(shí)表示不需要調(diào)整,也就是說此時(shí)已經(jīng)都是有序的了骂删,這個(gè)時(shí)候就不需要調(diào)整了掌动。

程序的基本框架已經(jīng)完成了,剩下的就是如何編寫調(diào)整函數(shù)了宁玫。調(diào)整的算法如下:

  1. 首先定義兩個(gè)指針粗恢,指向最右側(cè)和最左側(cè),最左側(cè)指針指向基準(zhǔn)數(shù)所在位置


  1. 先從右往左掃描欧瘪,當(dāng)發(fā)現(xiàn)右側(cè)數(shù)小于基準(zhǔn)值時(shí)眷射,將基準(zhǔn)值位置的數(shù)替換為該數(shù),并且立刻從左往右掃描,直到找到一個(gè)數(shù)大于基準(zhǔn)值妖碉,再次進(jìn)行替換


  2. 接著再次從右往左掃描涌庭,直到找到小于基準(zhǔn)數(shù)的值;并再次改變掃描順序欧宜,直到調(diào)整完畢


最后直到兩個(gè)指針重合坐榆,此時(shí)重合的位置就是基準(zhǔn)值所在位置

根據(jù)這個(gè)思路,可以編寫如下代碼

int QuickSort(int a[], int nLow, int nHigh)
{
    if (nLow >= nHigh)
    {
        return -1;
    }

    int tmp = a[nLow];

    int i = nLow;
    int j = nHigh;

    while (i != j)
    {
        //先從右往左掃描冗茸,只到找到比基準(zhǔn)值小的數(shù)
        //將該數(shù)放到基準(zhǔn)值的左側(cè)
        while (a[j] > tmp && j > i)
        {
            j--;
        }
        if (a[j] < tmp)
        {
            a[i]= a[j];
            i++;
        }

        //接著從左往右掃描席镀,直到找到比基準(zhǔn)值大的數(shù)
        //將該數(shù)放入到基準(zhǔn)值的右側(cè)
        while (a[i] < tmp && i < j)
        {
            i++;
        }
        
        if (a[i] > tmp)
        {
            a[j] = a[i];

            j--;
        }
    }
    
    a[i] = tmp;
    return i;
}

到此已經(jīng)完成了快速排序的算法編寫了。

在有大量的數(shù)據(jù)需要進(jìn)行排序時(shí)快速排序的效果比較好夏漱,如果數(shù)據(jù)量小豪诲,或者排序的序列已經(jīng)是一個(gè)逆序的有序序列,它退化成O(n^2)挂绰。

快速排序是一個(gè)不穩(wěn)定的排序算法屎篱。
<hr />

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市葵蒂,隨后出現(xiàn)的幾起案子交播,更是在濱河造成了極大的恐慌,老刑警劉巖刹勃,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件堪侯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡荔仁,警方通過查閱死者的電腦和手機(jī)伍宦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乏梁,“玉大人次洼,你說我怎么就攤上這事∮銎铮” “怎么了卖毁?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)落萎。 經(jīng)常有香客問我,道長(zhǎng)练链,這世上最難降的妖魔是什么翔脱? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮媒鼓,結(jié)果婚禮上届吁,老公的妹妹穿的比我還像新娘错妖。我一直安慰自己,他們只是感情好疚沐,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布暂氯。 她就那樣靜靜地躺著,像睡著了一般亮蛔。 火紅的嫁衣襯著肌膚如雪痴施。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天尔邓,我揣著相機(jī)與錄音晾剖,去河邊找鬼。 笑死梯嗽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沽损。 我是一名探鬼主播灯节,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绵估!你這毒婦竟也來了炎疆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤国裳,失蹤者是張志新(化名)和其女友劉穎形入,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缝左,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亿遂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了渺杉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛇数。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖是越,靈堂內(nèi)的尸體忽然破棺而出耳舅,到底是詐尸還是另有隱情,我是刑警寧澤倚评,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布浦徊,位于F島的核電站,受9級(jí)特大地震影響天梧,放射性物質(zhì)發(fā)生泄漏盔性。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一腿倚、第九天 我趴在偏房一處隱蔽的房頂上張望纯出。 院中可真熱鬧蚯妇,春花似錦、人聲如沸暂筝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽焕襟。三九已至陨收,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鸵赖,已是汗流浹背务漩。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留它褪,地道東北人饵骨。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像茫打,于是被迫代替她去往敵國(guó)和親居触。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348