最優(yōu)二叉樹

基本概念

給定n個權值作為n的[葉子]結點浩销,構造一棵二叉樹膘侮,若帶權路徑長度達到最小适瓦,稱這樣的二叉樹為最優(yōu)二叉樹玄渗,也稱為哈夫曼樹(Huffman Tree)妻顶。哈夫曼樹是帶權路徑長度最短的樹条霜,權值較大的結點離根較近蛾绎。

思路
將輸入的每一個葉子節(jié)點權值存入數(shù)組arr[]中宋光,并將每一個葉子節(jié)點建成一顆樹情连,存入數(shù)組tree[]中叽粹,因為有n個葉子節(jié)點,所以建立最優(yōu)二叉樹需要n-1步却舀,每次在arr[]數(shù)組中找到最小的兩個值虫几,建立一個新的節(jié)點,存入tree[]中挽拔,將新節(jié)點的權值存入arr[]中辆脸,最終建成一顆最優(yōu)二叉樹。

定義節(jié)點

struct treenode {
    int data;      
    treenode *lch;    //左孩子
    treenode *rch;   //右孩子
};

建立最優(yōu)二叉樹

treenode *huffmanTree(int n) {  //n為葉子個數(shù)
    int index = 0;        
    for (int i = 0; i < n; ++i) {  //將每一個葉子節(jié)點建成一棵樹螃诅,放入數(shù)組tree[]中
        treenode *p = new treenode;
        p->data = arr[i];   //arr[]中放著葉子節(jié)點的權值
        p->lch = NULL;
        p->rch = NULL;
        tree[index++] = p;
    }
    treenode *root = NULL;   //定義最優(yōu)二叉樹的根
    for (int i = 0; i < n - 1; ++i) { //每次取arr[]中未使用的最小兩個值
        sort(arr + i, arr + n);
        treenode *ch1 = NULL, *ch2 = NULL;
        for (int j = 0; j < index; ++j) {//在數(shù)組tree[]中找到這兩個值啡氢,建立新的節(jié)點
            if(tree[j]->data == arr[i])
                ch1 = tree[j];
            if(tree[j]->data == arr[i + 1])
                ch2 = tree[j];
            if(ch1 && ch2) break;
        }
        treenode *p = new treenode;//建立新的節(jié)點,存入數(shù)組tree[]中
        p->data = ch1->data + ch2->data;
        p->lch = ch1;
        p->rch = ch2;
        root = p;//更新根术裸,直到建立完成
        tree[index++] = p;
        arr[i + 1] = p->data;//并將這個節(jié)點的權值傳入數(shù)組arr[]中
    }
    return root;
}

計算權值WPL

結點的權及帶權路徑長度
若將樹中結點賦給一個有著某種含義的數(shù)值倘是,則這個數(shù)值稱為該結點的權。結點的帶權路徑長度為:從根結點到該結點之間的路徑長度與該結點的權的乘積袭艺。
樹的帶權路徑長度
樹的帶權路徑長度規(guī)定為所有葉子結點的帶權路徑長度之和搀崭,記為WPL。

void weight(treenode *root, int n) {//n為樹當前的層數(shù)猾编,root為最優(yōu)二叉樹的根
    treenode *p = root;
    if(p != NULL) {
        if((p->lch) == NULL && (p->rch) == NULL) {//即當p為葉子節(jié)點時
            //cout << p->data << endl;
            w += n * (p->data);//w為最優(yōu)二叉樹的權值
        }
        weight(p->lch, n + 1);
        weight(p->rch, n + 1);
    }
}

C++代碼

#include <iostream>
#include <algorithm>
using namespace std;

const int MAX_N = 1e6;
int arr[MAX_N];
int w = 0;

struct treenode {
    int data;
    treenode *lch;
    treenode *rch;
};

treenode *tree[MAX_N];

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i)
        cin >> arr[i];
    treenode *root = NULL;
    root = huffmanTree(n);
    weight(root, 0);//注意0
    cout << w << endl;
    return 0;
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末瘤睹,一起剝皮案震驚了整個濱河市升敲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌轰传,老刑警劉巖驴党,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異获茬,居然都是意外死亡港庄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門锦茁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攘轩,“玉大人,你說我怎么就攤上這事码俩。” “怎么了歼捏?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵稿存,是天一觀的道長。 經常有香客問我瞳秽,道長瓣履,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任练俐,我火速辦了婚禮袖迎,結果婚禮上,老公的妹妹穿的比我還像新娘腺晾。我一直安慰自己燕锥,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布悯蝉。 她就那樣靜靜地躺著归形,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鼻由。 梳的紋絲不亂的頭發(fā)上暇榴,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音蕉世,去河邊找鬼蔼紧。 笑死,一個胖子當著我的面吹牛狠轻,可吹牛的內容都是我干的奸例。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼哈误,長吁一口氣:“原來是場噩夢啊……” “哼哩至!你這毒婦竟也來了躏嚎?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤菩貌,失蹤者是張志新(化名)和其女友劉穎卢佣,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箭阶,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡虚茶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了仇参。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘹叫。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖诈乒,靈堂內的尸體忽然破棺而出罩扇,到底是詐尸還是另有隱情,我是刑警寧澤怕磨,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布喂饥,位于F島的核電站,受9級特大地震影響肠鲫,放射性物質發(fā)生泄漏员帮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一导饲、第九天 我趴在偏房一處隱蔽的房頂上張望捞高。 院中可真熱鬧,春花似錦渣锦、人聲如沸硝岗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辈讶。三九已至,卻和暖如春娄猫,著一層夾襖步出監(jiān)牢的瞬間贱除,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工媳溺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留月幌,地道東北人。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓悬蔽,卻偏偏與公主長得像扯躺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容

  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結點至多有m個孩子录语。 除根結點和葉子結點外倍啥,其它每個結點至少有m...
    文檔隨手記閱讀 13,199評論 0 25
  • 四虽缕、樹與二叉樹 1. 二叉樹的順序存儲結構 二叉樹的順序存儲就是用數(shù)組存儲二叉樹。二叉樹的每個結點在順序存儲中都有...
    MinoyJet閱讀 1,512評論 0 7
  • 樹的概述 樹是一種非常常用的數(shù)據(jù)結構蒲稳,樹與前面介紹的線性表氮趋,棧,隊列等線性結構不同江耀,樹是一種非線性結構 1.樹的定...
    Jack921閱讀 4,442評論 1 31
  • 定義指針變量剩胁,如果不賦給它地址,系統(tǒng)會隨機給它分配一個地址祥国。 C++標準庫 C++ Standard Librar...
    縱我不往矣閱讀 286評論 0 1
  • 朱自清的荷塘月色可謂經典舌稀,描繪了一片月色下的幽靜荷塘索昂,可我只記得這一句話,熱鬧中帶著孤獨扩借,自我的孤獨與荷塘的熱鬧形...
    蝶水月秋千閱讀 518評論 0 0