樹的性質(zhì)(不定期更新)

完全二叉樹可以和數(shù)組完美轉(zhuǎn)換

若將完全二叉樹的節(jié)點按構(gòu)件順序進行編號(從0開始,即樹根節(jié)點編號為0)腌逢。

性質(zhì)1:節(jié)點i的兩個子節(jié)點的編號為2i+1和2i+2.

性質(zhì)2:由性質(zhì)1可得,當(dāng)i > 0 時,其父節(jié)點為 floor((i-1)/2)

性質(zhì)3:完全二叉樹中最后一個有子節(jié)點的節(jié)點為 n/2 - 1。 n為節(jié)點數(shù)量

利用頂堆的堆積排序:

大/小頂堆的性質(zhì):

1霞扬、頂堆一定是完全二叉樹,所以可以用數(shù)組直接表示

2枫振、大/小頂堆的每個子樹也是大/小頂堆

排序思路:

基本思想:把待排序的元素按照大小在二叉樹位置上排列喻圃,排序好的元素要滿足:父節(jié)點的元素要大于等于其子節(jié)點;這個過程叫做堆化過程粪滤,如果根節(jié)點存放的是最大的數(shù)斧拍,則叫做大根堆;如果是最小的數(shù)杖小,自然就叫做小根堆了肆汹。根據(jù)這個特性(大根堆根最大,小根堆根最杏枞ā)昂勉,就可以把根節(jié)點拿出來,然后再堆化下扫腺,再把根節(jié)點拿出來岗照,闪湾,凰棉,集漾,循環(huán)到最后一個節(jié)點症见,就排序好了。

參考1:https://blog.csdn.net/YuZhiHui_No1/article/details/44258297

參考2:http://www.seotest.cn/jishu/46956.html

實現(xiàn):

1舶赔、堆化過程:從最后一個分支結(jié)點(n div 2)開始臼朗,到根(1)為止胸蛛,依次對每個分支結(jié)點進行調(diào)整(下沉)习绢,以便形成以每個分支結(jié)點為根的堆,當(dāng)最后對樹根結(jié)點進行調(diào)整后,整個樹就變成了一個堆闪萄。

所謂下沉梧却,即將節(jié)點通過不斷與自己的子節(jié)點進行比較、交換败去,直到行進到某個位置使得自己是當(dāng)前子樹中最大或最小的放航。因為單獨的下沉過程并不能保證子樹的正確性。所以一定要從最下層有子節(jié)點的節(jié)點開始下沉圆裕,以保證整體算法的正確性广鳍。

2、方法是依次將堆的根節(jié)點數(shù)記下吓妆,然后刪除根節(jié)點赊时,如此反復(fù)直到堆為空。上面提到了刪除操作行拢,每次刪除之后都是要調(diào)整堆讓堆的性質(zhì)不變祖秒,即根節(jié)點必為最大值或最小值。

具體操作可以使每次都將根節(jié)點與當(dāng)前排序的數(shù)組片段的最后一位互換舟奠,然后對新數(shù)組的第一個元素進行下沉操作(并將進行堆化的數(shù)組長度-1)

由頂堆的性質(zhì)(或根據(jù)堆化的過程)可知竭缝,在排序階段,除每次的頂點外的其他頂點都是已經(jīng)經(jīng)過下沉操作的沼瘫,所以直接對新頂點進行下沉即可得到新的頂堆

#include "core.hpp"
void heap(int *data, int size);
void ad_heap(int *data, int i, int size);

void heap(int *data, int size){
    // int i, j, tmp;
    // 根據(jù)性質(zhì)可得抬纸,節(jié)點 i = size/2 -1 是最后一個有子節(jié)點的節(jié)點
    // 且i節(jié)點之前的所有節(jié)點都一定有兩個子樹
    // 從節(jié)點i開始向前,對所有節(jié)點進行下沉操作耿戚,保證當(dāng)前節(jié)點下的所有子樹的正確性
    for(int i=(size/2 - 1);i>=0;i--){
        ad_heap(data, i, size);
    }
    cout << "\n 堆積內(nèi)容:";
    print_array(data, size);
    for(int i = size - 2; i >0; i--){
        mswap(data[0], data[i+1]);              // 交換堆化后數(shù)組的第一個值和最后一個值湿故, mswap僅實現(xiàn)了數(shù)值交換
        ad_heap(data,0, i);                    // 對長度減一的數(shù)組的根節(jié)點進行下沉操作
    }
    print_array(data, size);

}


// 該函數(shù)的作用是將節(jié)點i的值下沉到正確位置,并不是將以i為頂點的二叉樹轉(zhuǎn)為頂堆
// 當(dāng)下沉到某個節(jié)點溅话,使得i的值比當(dāng)前節(jié)點兩個子節(jié)點斗大即完成下沉
// 子樹的正確性由調(diào)用函數(shù)保證
void ad_heap(int *data, int i, int size){
    cout << "called====================" << endl;
    int j, tmp, post;
    j = 2*i + 1;
    tmp = data[i];
    post = 0;
    while (j < size && post ==0){
        cout << "j: " << j << " i: " << i << " root: " << tmp  << " left: " << data[j] << endl;
        if(j < size && j+1 < size){        // 標(biāo)記左右子樹中最大的一個
            if(data[j] < data[j+1]){
                j++;
            }
        }
        if(tmp >= data[j]){                // 如果當(dāng)前節(jié)點比左右子樹都大則認(rèn)為下沉完成
            post = 1;                      // 不再進一步校驗下一層的原因是晓锻,默認(rèn)子樹已經(jīng)完成下沉,再進行校驗就是重復(fù)校驗了
        }
        else{
            data[(j-1)/2] = data[j];        // 當(dāng)前節(jié)點小于左節(jié)點或右節(jié)點飞几,需要交換該子節(jié)點的值與當(dāng)前根節(jié)點的值
            j = 2*j + 1;                    // 因為發(fā)生了交換砚哆,不能保證交換后的各個子樹仍然正確,故需要繼續(xù)對下一層進行檢查
        }
    }
    
    data[(j-1)/2] = tmp;
    print_array(data, size);
    cout << "end====================" << endl;

}


int main(){
    int data[8] = {34,19,40,14,57,17,4,43};
    heap(data, 8);
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末屑墨,一起剝皮案震驚了整個濱河市躁锁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卵史,老刑警劉巖战转,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異以躯,居然都是意外死亡槐秧,警方通過查閱死者的電腦和手機啄踊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刁标,“玉大人颠通,你說我怎么就攤上這事“蛐福” “怎么了顿锰?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長启搂。 經(jīng)常有香客問我硼控,道長,這世上最難降的妖魔是什么胳赌? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任牢撼,我火速辦了婚禮,結(jié)果婚禮上匈织,老公的妹妹穿的比我還像新娘浪默。我一直安慰自己,他們只是感情好缀匕,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布纳决。 她就那樣靜靜地躺著,像睡著了一般乡小。 火紅的嫁衣襯著肌膚如雪阔加。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天满钟,我揣著相機與錄音胜榔,去河邊找鬼。 笑死湃番,一個胖子當(dāng)著我的面吹牛夭织,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吠撮,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尊惰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泥兰?” 一聲冷哼從身側(cè)響起弄屡,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鞋诗,沒想到半個月后膀捷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡削彬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年全庸,在試婚紗的時候發(fā)現(xiàn)自己被綠了秀仲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡壶笼,死狀恐怖啄育,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拌消,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布安券,位于F島的核電站墩崩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏侯勉。R本人自食惡果不足惜鹦筹,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望址貌。 院中可真熱鬧铐拐,春花似錦、人聲如沸练对。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽螟凭。三九已至虚青,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間螺男,已是汗流浹背棒厘。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留下隧,地道東北人奢人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像淆院,于是被迫代替她去往敵國和親何乎。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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

  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系迫筑,并對這種結(jié)構(gòu)定義相應(yīng)的運算宪赶,而且確保經(jīng)過這...
    Winterfell_Z閱讀 5,794評論 0 13
  • 1)這本書為什么值得看: Python語言描述,如果學(xué)的Python用這本書學(xué)數(shù)據(jù)結(jié)構(gòu)更合適 2016年出版脯燃,內(nèi)容...
    孫懷闊閱讀 12,466評論 0 15
  • <希爾排序> 詳細(xì)代碼請參考Algorithm搂妻。參考代碼比文字好理解。希爾排序辕棚,也稱遞減增量排序算法欲主,是插入排序的...
    明明的魔樣閱讀 1,741評論 0 1
  • 概述 排序有內(nèi)部排序和外部排序邓厕,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進行排序,而外部排序是因排序的數(shù)據(jù)很大扁瓢,一次不能容納全部...
    蟻前閱讀 5,183評論 0 52
  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,253評論 0 2