簡(jiǎn)明快速排序?qū)懛?/h1>

快速排序代碼有幾個(gè)坑需要注意:
1豁鲤,partition的過程比較復(fù)雜,很容易出錯(cuò),某些行數(shù)很短的代碼很簡(jiǎn)潔但是不容易看懂典挑,不如采用簡(jiǎn)單直觀的方法:用第一個(gè)元素作為軸、partition結(jié)束之后再把軸swap到中間
2啦吧,選軸如果固定選第一個(gè)您觉,可能進(jìn)入worst case,復(fù)雜度退化為N2授滓,使用隨機(jī)選軸來解決這個(gè)問題
3琳水,如果有大量重復(fù)元素,快速排序同樣會(huì)陷入N2般堆,此時(shí)需要使用三向快速排序:將數(shù)組分為小于在孝、等于、大于軸的三部分郁妈,我們可以通過兩步partition來完成:首先分為小于等于浑玛、大于的兩部分,然后再進(jìn)行一次partition噩咪,拆分成三部分顾彰。

package com.mocyx.algs.sort;

import java.util.Random;
import java.util.Scanner;

/**
 * @author Administrator
 */
public class FastSort {
    static int[] arrs;
    static void swap(int a, int b) {
        int v = arrs[a];
        arrs[a] = arrs[b];
        arrs[b] = v;
    }

    static Random random = new Random(System.currentTimeMillis());

    static void choosePovit(int s, int e) {
        int m = s + random.nextInt(e - s);
        swap(s, m);
    }

    /**
     * @param s
     * @param e
     * @param leftEqual true表示把相等的放在左邊,false表示把相等的放在右邊
     * @return
     */
    static int partition(int s, int e, boolean leftEqual) {

        int i = s + 1;
        int j = e;
        int pivotValue = arrs[s];
        while (true) {
            if (leftEqual) {
                while (i <= e && arrs[i] <= pivotValue) {
                    i += 1;
                }
                while (j >= s + 1 && arrs[j] > pivotValue) {
                    j -= 1;
                }
            } else {
                while (i <= e && arrs[i] < pivotValue) {
                    i += 1;
                }
                while (j >= s + 1 && arrs[j] >= pivotValue) {
                    j -= 1;
                }
            }
            if (i <= e && j >= s + 1 && i <= j) {
                swap(i, j);
                i += 1;
                j -= 1;
            }else {
                break;
            }
        }
        swap(s, i - 1);
        return i - 1;
    }

    static void sort(int s, int e, int depth) {
        if (s >= e) {
            return;
        }
        //隨機(jī)選擇軸胃碾,避免進(jìn)入worst case
        choosePovit(s, e);
        //第一次partition涨享,小于等于軸的置換到軸右邊
        int mr = partition(s, e, true);
        //第二次partition,把等于軸的置換到右側(cè)
        swap(s, mr);
        int ml = partition(s, mr, false);
        //現(xiàn)在數(shù)組分為三塊:小于軸 等于軸 大于軸的
        sort(s, ml - 1, depth + 1);
        sort(mr + 1, e, depth + 1);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int c = scanner.nextInt();
        arrs = new int[c];
        for (int i = 0; i < c; i++) {
            arrs[i] = scanner.nextInt();
        }
        sort(0, arrs.length - 1, 1);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < arrs.length; i++) {
            stringBuilder.append(String.format("%d ", arrs[i]));
        }
        System.out.print(stringBuilder.toString());
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者

  • 序言:七十年代末仆百,一起剝皮案震驚了整個(gè)濱河市厕隧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖吁讨,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件髓迎,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡建丧,警方通過查閱死者的電腦和手機(jī)排龄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翎朱,“玉大人橄维,你說我怎么就攤上這事∷┣” “怎么了争舞?”我有些...
    開封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澈灼。 經(jīng)常有香客問我竞川,道長,這世上最難降的妖魔是什么叁熔? 我笑而不...
    開封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任流译,我火速辦了婚禮,結(jié)果婚禮上者疤,老公的妹妹穿的比我還像新娘。我一直安慰自己叠赦,他們只是感情好驹马,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著除秀,像睡著了一般糯累。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上册踩,一...
    開封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天泳姐,我揣著相機(jī)與錄音,去河邊找鬼暂吉。 笑死胖秒,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的慕的。 我是一名探鬼主播阎肝,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼肮街!你這毒婦竟也來了风题?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎沛硅,沒想到半個(gè)月后眼刃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摇肌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年擂红,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朦蕴。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡篮条,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吩抓,到底是詐尸還是另有隱情涉茧,我是刑警寧澤,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布疹娶,位于F島的核電站伴栓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏雨饺。R本人自食惡果不足惜钳垮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望额港。 院中可真熱鬧饺窿,春花似錦、人聲如沸移斩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽向瓷。三九已至肠套,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間猖任,已是汗流浹背你稚。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朱躺,地道東北人刁赖。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像室琢,于是被迫代替她去往敵國和親乾闰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361