快速排序算法

簡(jiǎn)介

快速排序(Quicksort)是對(duì)冒泡排序的一種改進(jìn)烈涮。
創(chuàng)始人:C. A. R. Hoare
出現(xiàn)的時(shí)間:1960年

快速排序算法的原理

基本思想

通過(guò)一趟排序?qū)⒁判虻臄?shù)據(jù)分割成獨(dú)立的兩部分,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小吁系,然后再按此方法對(duì)這兩部分?jǐn)?shù)據(jù)分別進(jìn)行快速排序药版,整個(gè)排序過(guò)程可以遞歸進(jìn)行辑舷,以此達(dá)到整個(gè)數(shù)據(jù)變成有序

簡(jiǎn)單說(shuō)明
  1. 通過(guò)設(shè)置分界值將原序列分為兩部分,(現(xiàn)在討論升序的情況槽片,降序則相反)左邊部分的所有值都小于或等于分界值何缓,右邊部分的所有值都大于或等于分界值。然后進(jìn)行步驟2还栓。
  2. 對(duì)步驟1中產(chǎn)生的兩部分分別再次按步驟1執(zhí)行一次歌殃。(這里其實(shí)已經(jīng)產(chǎn)生了遞歸)
具體步驟
  1. 首先設(shè)定一個(gè)分界值,通過(guò)該分界值將數(shù)組分成左右兩部分蝙云。

  2. 將大于或等于分界值的數(shù)據(jù)集中到數(shù)組右邊氓皱,小于分界值的數(shù)據(jù)集中到數(shù)組的左邊。此時(shí),左邊部分中各元素都小于或等于分界值波材,而右邊部分中各元素都大于或等于分界值股淡。

  3. 然后,左邊和右邊的數(shù)據(jù)可以獨(dú)立排序廷区。對(duì)于左側(cè)的數(shù)組數(shù)據(jù)唯灵,又可以取一個(gè)分界值,將該部分?jǐn)?shù)據(jù)分成左右兩部分隙轻,同樣在左邊放置較小值埠帕,右邊放置較大值。右側(cè)的數(shù)組數(shù)據(jù)也可以做類似處理玖绿。

  4. 重復(fù)上述過(guò)程敛瓷,可以看出,這是一個(gè)遞歸定義斑匪。通過(guò)遞歸將左側(cè)部分排好序后呐籽,再遞歸排好右側(cè)部分的順序。當(dāng)左蚀瘸、右兩個(gè)部分各數(shù)據(jù)排序完成后狡蝶,整個(gè)數(shù)組的排序也就完成了。

對(duì)具體步驟的解釋

對(duì)上面具體步驟的抽象解釋如下:

  • 對(duì)與一個(gè)數(shù)組設(shè)置一個(gè)分界值贮勃,然后用分界值與數(shù)組中的每一個(gè)元素(除分界值自己外)比較贪惹,所有滿足條件的(比如升序,被對(duì)比元素的元素應(yīng)該小于分界值)元素應(yīng)該從數(shù)組頭部開(kāi)始依次往尾部方插入寂嘉;相反馍乙,所有-不滿足條件的元素應(yīng)該從數(shù)組的尾部開(kāi)始依次往頭部方向插入。
  • 分界值自己除了作為對(duì)比值垫释,還充當(dāng)了空位置的角色丝格,用于安置(實(shí)際上就是交換)滿足或不滿足條件的元素。

有了上面的介紹棵譬,相信你已經(jīng)對(duì)快速算法有了一個(gè)基本的認(rèn)識(shí)显蝌,下面來(lái)看一個(gè)例子:
對(duì)數(shù)組[3,1,4,2,5]使用快速排序算法(升序),主要說(shuō)明一趟排序(相當(dāng)于遞歸調(diào)用的第一層)過(guò)程:

  1. 設(shè)置臨界值為3
  2. 3和5比較订咸,滿足升序曼尊,不交換
  3. 3和2比較,不滿足升序脏嚷,交換骆撇,數(shù)組變?yōu)椋?code>[2,1,4,3,5]
  4. 3和1比較,滿足升序父叙,不交換
  5. 3和4比較神郊,不滿足升序肴裙,交換,數(shù)組變?yōu)椋?code>[2,1,3,4,5]
  6. 一趟排序完成
    (說(shuō)白了就是臨界值一直充當(dāng)被交換的角色涌乳,不斷的把在前的不滿足條件的元素往后挪蜻懦,在后的滿足條件的元素往前挪,所以它自己也要不斷的前后移動(dòng)夕晓,直到找到真正屬于它的位置)

快速排序算法的Java實(shí)現(xiàn)

核心代碼

public void sort(boolean isAscending) {
        int[] data = super.getData();
        if (data == null || data.length < 2) {
            return;
        }
        //一趟排序
        this.quickSort(0, data.length - 1, isAscending);
    }

    //快速排序方法需要三個(gè)關(guān)鍵參數(shù)宛乃,設(shè)置排序區(qū)間的頭、尾數(shù)組下標(biāo)和排序方式標(biāo)志
    private void quickSort(int headIndex, int tailIndex, final boolean isAscending) {
        if (tailIndex - headIndex < 0) return;
        int[] data = super.getData();
        int key = data[headIndex];
        int i = headIndex, j = tailIndex;
        boolean isTail = true;
        while (i != j) {
            if (isTail) {
                boolean c1 = isAscending && data[j] < key;
                boolean c2 = !isAscending && data[j] > key;
                if (c1 || c2) {
                    swap(data, i, j);
                    i++;
                    isTail = false;
                    continue;
                }
                j--;
            } else {
                boolean c1 = isAscending && data[i] > key;
                boolean c2 = !isAscending && data[i] < key;
                if (c1 || c2) {
                    swap(data, i, j);
                    j--;
                    isTail = true;
                    continue;
                }
                i++;
            }
        }
         //遞歸排序
        this.quickSort(headIndex, i - 1, isAscending);
        this.quickSort(i + 1, tailIndex, isAscending);
    }

全部代碼(包導(dǎo)入信息自己設(shè)置)
AbstractSort.java

public abstract class AbstractSort {
    private int[] data;

    public AbstractSort(int[] data) {
        this.data = data;
    }

    public abstract void sort(boolean isAscending);

    public void sort() {
        this.sort(true);
    }

    public int[] getData() {
        return data;
    }

    public void print() {
        for (int i : this.data) {
            System.out.println(i);
        }
    }

    protected void swap(int[] data, int indexA, int indexB) {
        int temp = data[indexA];
        data[indexA] = data[indexB];
        data[indexB] = temp;
    }
}

QuickSort.java

public class QuickSort extends AbstractSort {
    public QuickSort(int[] data) {
        super(data);
    }

    @Override
    public void sort(boolean isAscending) {
        int[] data = super.getData();
        if (data == null || data.length < 2) {
            return;
        }
        this.quickSort(0, data.length - 1, isAscending);
    }

    private void quickSort(int headIndex, int tailIndex, final boolean isAscending) {
        if (tailIndex - headIndex < 0) return;
        int[] data = super.getData();
        int key = data[headIndex];
        int i = headIndex, j = tailIndex;
        boolean isTail = true;
        while (i != j) {
            if (isTail) {
                boolean c1 = isAscending && data[j] < key;
                boolean c2 = !isAscending && data[j] > key;
                if (c1 || c2) {
                    swap(data, i, j);
                    i++;
                    isTail = false;
                    continue;
                }
                j--;
            } else {
                boolean c1 = isAscending && data[i] > key;
                boolean c2 = !isAscending && data[i] < key;
                if (c1 || c2) {
                    swap(data, i, j);
                    j--;
                    isTail = true;
                    continue;
                }
                i++;
            }
        }
        this.quickSort(headIndex, i - 1, isAscending);
        this.quickSort(i + 1, tailIndex, isAscending);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蒸辆,一起剝皮案震驚了整個(gè)濱河市征炼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌躬贡,老刑警劉巖谆奥,帶你破解...
    沈念sama閱讀 211,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異逗宜,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)空骚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)纺讲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人囤屹,你說(shuō)我怎么就攤上這事熬甚。” “怎么了肋坚?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,435評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵乡括,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我智厌,道長(zhǎng)诲泌,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,509評(píng)論 1 284
  • 正文 為了忘掉前任铣鹏,我火速辦了婚禮敷扫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诚卸。我一直安慰自己葵第,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,611評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布合溺。 她就那樣靜靜地躺著卒密,像睡著了一般。 火紅的嫁衣襯著肌膚如雪棠赛。 梳的紋絲不亂的頭發(fā)上哮奇,一...
    開(kāi)封第一講書(shū)人閱讀 49,837評(píng)論 1 290
  • 那天膛腐,我揣著相機(jī)與錄音,去河邊找鬼屏镊。 笑死依疼,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的而芥。 我是一名探鬼主播律罢,決...
    沈念sama閱讀 38,987評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼棍丐!你這毒婦竟也來(lái)了误辑?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,730評(píng)論 0 267
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤歌逢,失蹤者是張志新(化名)和其女友劉穎巾钉,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體秘案,經(jīng)...
    沈念sama閱讀 44,194評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砰苍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,525評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阱高。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赚导。...
    茶點(diǎn)故事閱讀 38,664評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖赤惊,靈堂內(nèi)的尸體忽然破棺而出吼旧,到底是詐尸還是另有隱情,我是刑警寧澤未舟,帶...
    沈念sama閱讀 34,334評(píng)論 4 330
  • 正文 年R本政府宣布圈暗,位于F島的核電站,受9級(jí)特大地震影響裕膀,放射性物質(zhì)發(fā)生泄漏员串。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,944評(píng)論 3 313
  • 文/蒙蒙 一昼扛、第九天 我趴在偏房一處隱蔽的房頂上張望昵济。 院中可真熱鬧,春花似錦野揪、人聲如沸访忿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,764評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)海铆。三九已至,卻和暖如春挣惰,著一層夾襖步出監(jiān)牢的瞬間卧斟,已是汗流浹背殴边。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,997評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留珍语,地道東北人锤岸。 一個(gè)月前我還...
    沈念sama閱讀 46,389評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像板乙,于是被迫代替她去往敵國(guó)和親是偷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,554評(píng)論 2 349

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

  • 版本記錄 前言 將數(shù)據(jù)結(jié)構(gòu)和算法比作計(jì)算機(jī)的基石毫不為過(guò)募逞,追求程序的高效是每一個(gè)軟件工程師的夢(mèng)想蛋铆。下面就是我對(duì)算法...
    刀客傳奇閱讀 5,132評(píng)論 4 72
  • 前言 快速排序(Quicksort)是對(duì)冒泡排序的一種改進(jìn)》沤樱快速排序由C. A. R. Hoare在1962年提出...
    叫我不矜持閱讀 980評(píng)論 1 5
  • n:數(shù)據(jù)規(guī)模刺啦; 穩(wěn)定:兩個(gè)相等的值在排序前后相對(duì)位置是否改變,如果不會(huì)改變則成為穩(wěn)定纠脾,反之為不穩(wěn)定玛瘸; 排序方式:內(nèi)...
    undefined汪少閱讀 842評(píng)論 0 49
  • 引言 快速排序是應(yīng)用最廣泛的排序算法(C++中的sort函數(shù)內(nèi)部就是快排),優(yōu)點(diǎn)是實(shí)現(xiàn)簡(jiǎn)單苟蹈,速度快(時(shí)間復(fù)雜度Nl...
    StormZhu閱讀 1,480評(píng)論 0 4
  • 前言 前段時(shí)間糊渊,前端圈子因?yàn)橐黄恼旅嬖嚬伲喝钜环灏娴目焖倥判蛲耆清e(cuò)的,而浮躁了起來(lái)汉操,而本文作者也因?yàn)椴划?dāng)?shù)谋硎?..
    Kaku_fe閱讀 1,979評(píng)論 3 3