【算法】堆排序整理

畢業(yè)久了涨享,越是基礎(chǔ)的東西忘得越徹底,最近也是趁著有時(shí)間仆百,趕緊將這些補(bǔ)一補(bǔ)厕隧。說到堆排序,是這些排序算法中最后一個(gè)重新理解的算法俄周,究其原因吁讨,應(yīng)該是其實(shí)現(xiàn)的復(fù)雜要高于其他幾個(gè)算法。

堆排序的結(jié)構(gòu)形態(tài)是用一個(gè)數(shù)組實(shí)現(xiàn)了一個(gè)二叉樹栈源,堆分為最大堆和最小堆兩種挡爵,最大堆指的是該二叉樹的任意一個(gè)父節(jié)點(diǎn)都比其相連的子節(jié)點(diǎn)大,最小堆則反之甚垦。對(duì)于最大堆來說茶鹃,其根節(jié)點(diǎn)就是整個(gè)堆的最大值。

那么對(duì)于堆排序算法來說艰亮,主要做的是兩件事闭翩,首先是建堆,之后可以通過堆來依次獲取大小有序的數(shù)值迄埃,每取一個(gè)值都需要重新調(diào)整堆來保持堆的正確性疗韵。

建堆過程稍微復(fù)雜一些,以最大堆為例侄非,首先【倒序遍歷】含有子節(jié)點(diǎn)的節(jié)點(diǎn)蕉汪,【比較】其值與子節(jié)點(diǎn)的值,如果子節(jié)點(diǎn)的值更大的話逞怨,則該節(jié)點(diǎn)的值與其子節(jié)點(diǎn)的值進(jìn)行【交換】者疤。交換完成后,需要從子節(jié)點(diǎn)的位置繼續(xù)判斷其子節(jié)點(diǎn)是否比其大叠赦,如果是的話也進(jìn)行交換驹马,這樣依次【向下傳遞調(diào)整】,直到子節(jié)點(diǎn)不比父節(jié)點(diǎn)大或者已經(jīng)到達(dá)葉子節(jié)點(diǎn)為止。

對(duì)于關(guān)鍵步驟已經(jīng)通過【】標(biāo)注出來了糯累,整個(gè)建堆過程有點(diǎn)類似冒泡排序在二叉樹上面的實(shí)現(xiàn)算利。完成以上步驟就可以獲得一個(gè)最大堆。

之后的步驟是獲取排序結(jié)果泳姐,代碼在實(shí)現(xiàn)的時(shí)候比較有意思了效拭,首先取出堆頂?shù)臄?shù),讓其與數(shù)組最后一個(gè)數(shù)進(jìn)行交換胖秒,之后我們將數(shù)組最后一個(gè)數(shù)從堆里面排除出去允耿,之后從根節(jié)點(diǎn)開始,對(duì)堆做一次【向下傳遞調(diào)整】操作扒怖,那么我們最大值就跑數(shù)組最后面去了;第二次业稼,我們?cè)偃《秧數(shù)臄?shù)盗痒,讓其與數(shù)組最后第二個(gè)數(shù)進(jìn)行交換,之后我們將數(shù)組最后兩個(gè)數(shù)從堆里面排除出去低散,之后從根節(jié)點(diǎn)開始俯邓,對(duì)堆做一次【向下傳遞調(diào)整】操作。這樣一次進(jìn)行取數(shù)熔号、交換稽鞭、跳轉(zhuǎn)的操作,總共進(jìn)行N-1次后引镊,我們會(huì)發(fā)現(xiàn)我們的數(shù)組已經(jīng)以一個(gè)從小到大的進(jìn)行排序了朦蕴。這就是堆排序的整個(gè)過程。

c++代碼實(shí)現(xiàn)如下

// 最大堆排序 -- 獲取從小到大排序的結(jié)果

#include <iostream>
using namespace std;

void swep(int i, int j, int *unsortArray) {
    int temp = unsortArray[i];
    unsortArray[i] = unsortArray[j];
    unsortArray[j] = temp;
}

// 調(diào)整節(jié)點(diǎn)
void adjustCurrent(int index, int* unsortArray, int size) {
    int indexSon1 = index * 2 + 1;
    int indexSon2 = index * 2 + 2;
    bool hasNodeSon1 = (indexSon1 < size); //有第一個(gè)子節(jié)點(diǎn)
    bool hasNodeSon2 = (indexSon2 < size); //有第二個(gè)子節(jié)點(diǎn)
    if (!hasNodeSon1)
    {
        //沒有子節(jié)點(diǎn)不做處理
        return;
    }
    if (unsortArray[index] < unsortArray[indexSon1] 
        || (hasNodeSon2 && unsortArray[index] < unsortArray[indexSon2]))
    {
        int witchSweped = 1;
        if (hasNodeSon2)
        {
            //判斷兩個(gè)子節(jié)點(diǎn)中最大的是哪個(gè)
            if (unsortArray[indexSon1] > unsortArray[indexSon2])
            {
                swep(indexSon1, index, unsortArray);
            } else {
                swep(indexSon2, index, unsortArray);
                witchSweped = 2;
            }
        }
        else {
            swep(indexSon1, index, unsortArray);
        }
        //向下傳遞調(diào)整
        adjustCurrent(index * 2 + witchSweped, unsortArray, size);

    }
}

void heapSort(int *unsortArray, int size) {
    // 建堆
    for (int i = size/2 - 1; i >= 0; --i)
    {
        //當(dāng)前節(jié)點(diǎn)調(diào)整
        adjustCurrent(i, unsortArray, size);
    }

    // 通過堆獲取排序結(jié)果
    int currentIndex = size - 1;
    while(currentIndex) {
        swep(currentIndex, 0, unsortArray);
        adjustCurrent(0, unsortArray, currentIndex);
        currentIndex --;
    }
}

int main() {
    int unsortArray[] = {9,8,7,6,5,4,3,2,1};
    int size = sizeof(unsortArray)/sizeof(int);
    cout<<"before sort"<<endl;
    for (int i = 0; i < size; ++i)
    {
        cout<<unsortArray[i]<<" ";

    }
    cout<<endl;
    heapSort(unsortArray, size);


    cout<<"after sort"<<endl;
    for (int i = 0; i < size; ++i)
    {
        cout<<unsortArray[i]<<" ";
    }
    cout<<endl;
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末弟头,一起剝皮案震驚了整個(gè)濱河市吩抓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赴恨,老刑警劉巖疹娶,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異伦连,居然都是意外死亡雨饺,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門惑淳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來额港,“玉大人,你說我怎么就攤上這事汛聚∏掳玻” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長叹哭。 經(jīng)常有香客問我忍宋,道長,這世上最難降的妖魔是什么风罩? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任糠排,我火速辦了婚禮,結(jié)果婚禮上超升,老公的妹妹穿的比我還像新娘入宦。我一直安慰自己,他們只是感情好室琢,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布乾闰。 她就那樣靜靜地躺著,像睡著了一般盈滴。 火紅的嫁衣襯著肌膚如雪涯肩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天巢钓,我揣著相機(jī)與錄音病苗,去河邊找鬼。 笑死症汹,一個(gè)胖子當(dāng)著我的面吹牛硫朦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播背镇,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼治唤,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼惶凝!你這毒婦竟也來了状原?” 一聲冷哼從身側(cè)響起藻三,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎济瓢,沒想到半個(gè)月后荠割,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旺矾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蔑鹦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片箕宙。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嚎朽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柬帕,到底是詐尸還是另有隱情哟忍,我是刑警寧澤狡门,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站锅很,受9級(jí)特大地震影響其馏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜爆安,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一叛复、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扔仓,春花似錦褐奥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至版保,卻和暖如春耍群,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背找筝。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慷吊,地道東北人袖裕。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像溉瓶,于是被迫代替她去往敵國和親急鳄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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

  • 1 序 2016年6月25日夜堰酿,帝都疾宏,天下著大雨,拖著行李箱和同學(xué)在校門口照了最后一張合照触创,搬離寢室打車去了提前租...
    RichardJieChen閱讀 5,076評(píng)論 0 12
  • 1 初級(jí)排序算法 排序算法關(guān)注的主要是重新排列數(shù)組元素坎藐,其中每個(gè)元素都有一個(gè)主鍵。排序算法是將所有元素主鍵按某種方...
    深度沉迷學(xué)習(xí)閱讀 1,391評(píng)論 0 1
  • 概述 排序有內(nèi)部排序和外部排序哼绑,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序岩馍,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    蟻前閱讀 5,167評(píng)論 0 52
  • 概述:排序有內(nèi)部排序和外部排序抖韩,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序蛀恩,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部...
    每天刷兩次牙閱讀 3,727評(píng)論 0 15
  • 戎旅生涯茂浮,躍馬提刀双谆,敵寇膽顫心驚壳咕。 率眾沖鋒,屢立戰(zhàn)功顽馋,軍中英名傳頌谓厘。 轉(zhuǎn)戰(zhàn)后勤,敬業(yè)圖精趣避,美味佳肴飄香庞呕。 威武英...
    典桂閱讀 467評(píng)論 10 19