堆排序

堆是一棵順序存儲的完全二叉樹丈甸。

其中每個結(jié)點(diǎn)的關(guān)鍵字都不大于其孩子結(jié)點(diǎn)的關(guān)鍵字线得,這樣的堆稱為小根堆够话。

其中每個結(jié)點(diǎn)的關(guān)鍵字都不小于其孩子結(jié)點(diǎn)的關(guān)鍵字蓝翰,這樣的堆稱為大根堆。


圖1

如上圖所示女嘲,序列R{3, 8, 15, 31, 25}是一個典型的小根堆畜份。

舉例來說,對于n個元素的序列{R0, R1, ... , Rn}當(dāng)且僅當(dāng)滿足下列關(guān)系之一時欣尼,稱之為堆:

(1) Ri <= R2i+1 且 Ri <= R2i+2 (小根堆)

(2) Ri >= R2i+1 且 Ri >= R2i+2 (大根堆)

其中i=1,2,…,n/2向下取整;

堆排序要點(diǎn)

(1)根據(jù)初始數(shù)組去構(gòu)造初始堆(構(gòu)建一個完全二叉樹爆雹,保證所有的父結(jié)點(diǎn)都比它的孩子結(jié)點(diǎn)數(shù)值大)。

(2)每次交換第一個和最后一個元素愕鼓,輸出最后一個元素(最大值)钙态,然后把剩下元素重新調(diào)整為大根堆。

當(dāng)輸出完最后一個元素后菇晃,這個數(shù)組已經(jīng)是按照從小到大的順序排列了册倒。

先通過詳細(xì)的實(shí)例圖來看一下,如何構(gòu)建初始堆磺送。

設(shè)有一個無序序列 { 1, 3, 4, 5, 2, 6, 9, 7, 8, 0 }驻子。


圖片2

構(gòu)造了初始堆后,我們來看一下完整的堆排序處理:
還是針對前面提到的無序序列 { 1, 3, 4, 5, 2, 6, 9, 7, 8, 0 } 來加以說明册着。


圖片3

先給初始堆做個排序拴孤,如圖
排序.jpg

根據(jù)二叉樹性質(zhì):
如果一棵樹有n個節(jié)點(diǎn)的完全二叉樹,
如果2i+1>n, 則節(jié)點(diǎn)i無左孩子甲捏,i為葉子節(jié)點(diǎn)演熟,否則,左孩子節(jié)點(diǎn)是2i+1.
如果2i+2>n, 則節(jié)點(diǎn)i無由孩子,i為葉子節(jié)點(diǎn)芒粹,否則兄纺,右孩子節(jié)點(diǎn)是2i+2.

代碼實(shí)現(xiàn)
    public static void heapSort (int[] list) {
        // 循環(huán)建立初始堆
        for (int i=list.length/2-1; i>=0; i--) {
            HeapAdjust(list, i, list.length);
        }
        // 進(jìn)行n-1次循環(huán),完成排序
        for (int i=list.length-1; i>0; i--) {
            //最后一個元素和第一元素進(jìn)行交換
            swap(list, 0, i);
            //繼續(xù)構(gòu)建堆
            HeapAdjust(list, 0, i);
        }
    }

    public static void HeapAdjust(int[] list, int parent, int len) {
        //temp保存當(dāng)前父節(jié)點(diǎn)
        int temp = list[parent];
        //根據(jù)二叉樹性質(zhì)化漆,獲取左子樹
        int child = 2 * parent + 1;

        while (child < len) {
            //判斷是否有右子樹估脆,如果大于左子樹,選取右子樹節(jié)點(diǎn)
            if (child + 1 < len && list[child] < list[child+1]) {
                child++;
            }

            //如果父節(jié)點(diǎn)大于孩子節(jié)點(diǎn)座云,跳出循環(huán)
            if (temp > list[child]) {
                break;
            }

            //把孩子節(jié)點(diǎn)賦值給父節(jié)點(diǎn)疙赠,此時父節(jié)點(diǎn)和孩子節(jié)點(diǎn)值一樣
            list[parent] = list[child];
            parent = child;
            //繼續(xù)選取左孩子節(jié)點(diǎn)向下篩選
            child = 2*child + 1;
        }
        list[parent] = temp;
    }

    public static void swap(int[] list, int i, int j) {
        int temp = list[j];
        list[j] = list[i];
        list[i] = temp;
    }

    public static void main(String[] args) {
        int[] list = {1, 3, 4, 5, 2, 6, 9, 7, 8, 0};
        heapSort(list);
        for (int i=0; i<list.length; i++) {
            System.out.print(list[i] + ", ");
        }
    }

輸出結(jié)果:
Heap sort:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

時間復(fù)雜度是:O(nlogn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朦拖,隨后出現(xiàn)的幾起案子圃阳,更是在濱河造成了極大的恐慌,老刑警劉巖璧帝,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捍岳,死亡現(xiàn)場離奇詭異,居然都是意外死亡睬隶,警方通過查閱死者的電腦和手機(jī)锣夹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來苏潜,“玉大人银萍,你說我怎么就攤上這事〗严停” “怎么了砖顷?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赃梧。 經(jīng)常有香客問我滤蝠,道長,這世上最難降的妖魔是什么授嘀? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任物咳,我火速辦了婚禮,結(jié)果婚禮上蹄皱,老公的妹妹穿的比我還像新娘览闰。我一直安慰自己,他們只是感情好巷折,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布压鉴。 她就那樣靜靜地躺著,像睡著了一般锻拘。 火紅的嫁衣襯著肌膚如雪油吭。 梳的紋絲不亂的頭發(fā)上击蹲,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機(jī)與錄音婉宰,去河邊找鬼歌豺。 笑死,一個胖子當(dāng)著我的面吹牛心包,可吹牛的內(nèi)容都是我干的类咧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蟹腾,長吁一口氣:“原來是場噩夢啊……” “哼痕惋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起岭佳,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤血巍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后珊随,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柿隙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年叶洞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片禀崖。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡衩辟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出波附,到底是詐尸還是另有隱情艺晴,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布掸屡,位于F島的核電站封寞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仅财。R本人自食惡果不足惜狈究,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盏求。 院中可真熱鬧抖锥,春花似錦、人聲如沸碎罚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窖张。三九已至裸燎,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谜喊。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工潭兽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人斗遏。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓山卦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親诵次。 傳聞我的和親對象是個殘疾皇子账蓉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355