【算法】排序(五)快速排序

正文之前

快速排序(英語:Quicksort),又稱劃分交換排序(partition-exchange sort)亡蓉,一種排序算法晕翠,最早由東尼 * 霍爾提出。在平均狀況下砍濒,排序n個(gè)項(xiàng)目要O(nlogn)次比較淋肾,在最壞情況下則需要O(n2)次比較,但這種狀況并不常見爸邢。事實(shí)上樊卓,快速排序通常明顯比其他O(nlogn)算法更快,因?yàn)樗膬?nèi)部循環(huán)(inner loop)可以在大部分的架構(gòu)上很有效率地被實(shí)現(xiàn)出來杠河。??????????????——Wikipedia


本文將介紹以下內(nèi)容

排序原理
算法實(shí)現(xiàn)(JAVA)
測試階段
算法分析

正文

排序原理

和歸并排序劃清界限:

  • 歸并排序:將一個(gè)數(shù)組分成兩個(gè)字?jǐn)?shù)組碌尔,分別排序兩部分,將有序的子數(shù)組歸并得到整個(gè)有序數(shù)組

  • 快速排序:將一個(gè)數(shù)組分成兩個(gè)字?jǐn)?shù)組券敌,分別排序兩部分唾戚,當(dāng)兩個(gè)子數(shù)組有序時(shí),整個(gè)數(shù)組自然就有序了

快速排序使用一個(gè)切分元素來劃分?jǐn)?shù)組待诅,切分元素左邊的數(shù)組元素小于切分元素叹坦,右邊的數(shù)組元素大于于切分元素,所以兩個(gè)子數(shù)組有序就會(huì)得到整個(gè)有序的數(shù)組

算法實(shí)現(xiàn)

1. 切分?jǐn)?shù)組
private static int partition(int[] a, int low, int high){
        int i = low, j = high + 1;              //由兩邊向中間掃描
        int p = a[low];                         //切分?jǐn)?shù)組的元素
        while(true){
            while(a[++i] < p){                  // i 的值會(huì)一直遞增至 a[++i] >= p
                if(i == high){                  //掃描結(jié)束
                    break;
                }
            }
            while(a[--j] > p){                  // j 的值會(huì)一直遞減至 a[++i] >= p
                if(j == low){                   //掃描結(jié)束
                    break;
                }
            }

            if(i >= j){                         // j 的位置就是切分元素在有序數(shù)組中的位置
                break;
            }

            int temp = a[i];                    //交換元素順序
            a[i] = a[j];
            a[j] = temp;
        }

        int temp = a[low];                      //將切分元素交換至中間位置
        a[low] = a[j];
        a[j] = temp;

        return j;
    }
2. 數(shù)組排序

這一部分的代碼和歸并排序的排序代碼相似

private static void quickSort(int[] a){
        sort(a, 0, a.length - 1);
    }

    private static void sort(int[] a, int lo, int hi){
        if(hi <= lo){
            return ;
        }
        int j = partition(a, lo, hi);
        sort(a, lo, j - 1);
        sort(a, j + 1, hi);
    }

sort方法遞歸調(diào)用自己咱士,將數(shù)組劃分至最小立由,每次都將子序列中的第一個(gè)元素作為切分元素轧钓,來將數(shù)組排序

整個(gè)排序過程的代碼:
public class QuickSort {

    private static int partition(int[] a, int low, int high){
        int i = low, j = high + 1;              //由兩邊向中間掃描
        int p = a[low];                         //切分?jǐn)?shù)組的元素
        while(true){
            while(a[++i] < p){                  // i 的值會(huì)一直遞增至 a[++i] >= p
                if(i == high){                  //掃描結(jié)束
                    break;
                }
            }
            while(a[--j] > p){                  // j 的值會(huì)一直遞減至 a[++i] >= p
                if(j == low){                   //掃描結(jié)束
                    break;
                }
            }

            if(i >= j){                         // j 的位置就是切分元素在有序數(shù)組中的位置
                break;
            }

            int temp = a[i];                    //交換元素順序
            a[i] = a[j];
            a[j] = temp;
        }

        int temp = a[low];                      //將切分元素交換至中間位置
        a[low] = a[j];
        a[j] = temp;

        return j;
    }

    private static void quickSort(int[] a){
        sort(a, 0, a.length - 1);
    }

    private static void sort(int[] a, int lo, int hi){
        if(hi <= lo){
            return ;
        }
        int j = partition(a, lo, hi);
        sort(a, lo, j - 1);
        sort(a, j + 1, hi);
    }
}

測試階段

public static void main(String[] args){
        int[] a = new int[10];
        for (int i = 0; i < 10; i++) {
            a[i] = (int)(Math.random() * 100);
            System.out.print(a[i] + " ");
        }
        quickSort(a);
        System.out.println();
        for (int i = 0; i < 10; i++) {
            System.out.print(a[i] + " ");
        }
    }

生成10個(gè)隨機(jī)數(shù)字并調(diào)用快速排序方法序厉,最后輸出結(jié)果:

算法分析

1. 特點(diǎn)

快速排序?qū)崿F(xiàn)簡單,應(yīng)用廣泛毕箍,比一般算法要快很多弛房,并且是原地排序(借助輔助棧)

2. 時(shí)間復(fù)雜度
  1. 設(shè)數(shù)組的長度為N,用 T(N) 表示排序一個(gè)長度為N的數(shù)組所需要的比較次數(shù)而柑,可想而知文捶,T(0) 和 T(1) 為0

  2. 切分的成本為N + 1,左子數(shù)組排序的平均成本為(C1 + C2 + ... + CN - 2 + CN - 1)/N媒咳,右子數(shù)組排序的平均成本為(CN - 1 + CN - 2 + ... + C2 + CN)/N

  3. CN = N + 1 + (C1 + C2 + ... + CN - 2 + CN - 1)/N + (CN - 1 + CN - 2 + ... + C2 + CN)/N

  4. 經(jīng)過化簡之后得到:CN ~ 2(N + 1)(1/3 + 1/4 + ... + 1/(N + 1))

  5. 積分得到CN ~ 2NlogN

所以粹排,算法復(fù)雜度為 O(nlogn)

3. 穩(wěn)定性

舉個(gè)例子,一個(gè)數(shù)組a = [6,4,3,2,3,7,8,7,9]涩澡,a[0]和a[4]交換顽耳,第二個(gè) 3 就移動(dòng)到了第一個(gè) 3 的前面,所以是不穩(wěn)定的,不穩(wěn)定性體現(xiàn)在切分元素交換的時(shí)候

關(guān)于快速排序的介紹就到這里了射富,謝謝膝迎!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市胰耗,隨后出現(xiàn)的幾起案子限次,更是在濱河造成了極大的恐慌,老刑警劉巖柴灯,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件卖漫,死亡現(xiàn)場離奇詭異,居然都是意外死亡赠群,警方通過查閱死者的電腦和手機(jī)懊亡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乎串,“玉大人店枣,你說我怎么就攤上這事√居” “怎么了鸯两?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長长豁。 經(jīng)常有香客問我钧唐,道長,這世上最難降的妖魔是什么匠襟? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任钝侠,我火速辦了婚禮,結(jié)果婚禮上酸舍,老公的妹妹穿的比我還像新娘帅韧。我一直安慰自己,他們只是感情好啃勉,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布忽舟。 她就那樣靜靜地躺著,像睡著了一般淮阐。 火紅的嫁衣襯著肌膚如雪叮阅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天泣特,我揣著相機(jī)與錄音浩姥,去河邊找鬼。 笑死状您,一個(gè)胖子當(dāng)著我的面吹牛勒叠,可吹牛的內(nèi)容都是我干的镀裤。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼缴饭,長吁一口氣:“原來是場噩夢啊……” “哼暑劝!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起颗搂,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤担猛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后丢氢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體傅联,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年疚察,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒸走。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片貌嫡。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡比驻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岛抄,到底是詐尸還是另有隱情别惦,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布夫椭,位于F島的核電站掸掸,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蹭秋。R本人自食惡果不足惜扰付,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仁讨。 院中可真熱鬧羽莺,春花似錦、人聲如沸陪竿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽族跛。三九已至,卻和暖如春锐墙,著一層夾襖步出監(jiān)牢的瞬間礁哄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國打工溪北, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桐绒,地道東北人夺脾。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像茉继,于是被迫代替她去往敵國和親咧叭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 日月是報(bào)應(yīng)體 月日交替紅暈起 粉紅如那少女羞 這是不讓把覺睡烁竭? 人身不是神仙體 寄于人身沒法仙 萬般神通不能使 成...
    縱情嬉戲天地間閱讀 196評(píng)論 0 0
  • 曾經(jīng)流行的某個(gè)段子:握住老婆的手菲茬,就像左手握右手,一點(diǎn)感覺都沒有派撕。似乎是說夫妻之情極易平淡如水婉弹;但從另一角度又恰巧...
    Kaliraja閱讀 1,426評(píng)論 0 0
  • 原創(chuàng)四十篇(15/02/2017) ——從做“應(yīng)用題”到做“選擇題” 在中國這樣的大環(huán)境中,絕大多數(shù)的人都習(xí)慣了自...
    許文輝閱讀 937評(píng)論 0 1
  • 小編收集整理的項(xiàng)目都是經(jīng)過小編本人親自運(yùn)行測試(有的項(xiàng)目bug之多终吼,誰改誰知道镀赌,但是在小編的修改下都是可以運(yùn)行的,...
    摸著石頭過河_崖邊樹閱讀 369評(píng)論 0 0
  • 11看不見的努力!—你看到的上面這樣的照片其實(shí)是下面這樣拍出來的姆打。所以威彰,我們要感謝那些“看不見的努力”。
    geqi閱讀 274評(píng)論 6 4