SSL 1408 樹 哈夫曼樹 二

2021-10-25 14:14:30 字數 2085 閱讀 2409

time limit:1000ms

memory limit:65536k

有n(n<=26)個帶權結點,從a開始的n個字母分別表示這n個結點,他們分別代n個權值,試以它們為葉子結點構造一棵哈夫曼樹(請按照左子樹根節點的權小於等於右子樹根節點的權的次序構造,若兩結點相等時,按照字典順序分別為左子樹和右子樹)。 最後求出該哈夫曼樹的帶權路徑長度.

第一行為乙個n的值;第二行為n個字母,中間用空格分開;第三行為n個數字,分別表示著n個字母代表的數值.

共計n+1行,前n行分別為按照字母表的順序輸出各個字母和編碼,中間用冒號分開,第n+1行為該哈夫曼樹的帶權路徑長度

7

a b c d e f g37

8258

4

a:

1101

b:111

c:00

d:1100

e:101

f:01

g:100

100

是【ssl】1407【樹】哈夫曼樹(一)的公升級版

構造哈夫曼樹

中序遍歷遞迴找葉子節點和編碼

字典序排序

求帶權路徑長度

構造哈夫曼樹的基本思想是要讓權大的葉子離根最近。

具體作法是:

(1)根據給定的n個權值{w1,w2,…,wn},構造n棵二叉樹的集合f={t1,t2,…,tn},其中每棵二叉樹中均只含乙個帶權值為wi的根結點,其左、右子樹為空樹;

(2)在f中選取其根結點的權值為最小的兩棵二叉樹,分別作為左、右子樹構造一棵新的二叉樹,並置這棵新的二叉樹根結點的權值為其左、右子樹根結點的權值之和;

(3)從f中刪去這兩棵樹,同時加入剛生成的新樹;

(4)重複(2)和(3)兩步,直到f中只含一棵樹為止。

從上述演算法中可以看出,f實際上是森林,該演算法的思想是不斷地進行森林f中的二叉樹的「合併」,最終得到哈夫曼樹。

實際上,哈夫曼演算法的實現與實際問題所採用的儲存結構有關。現假設用陣列f來儲存哈夫曼樹,其中第i個陣列元素f[i]是哈夫曼樹中的乙個結點,其位址為i,有3個域,data域存放該結點的權值,lchild域和rchild域分別存放該結點左、右子樹的根結點的位址(下標)。在初始狀態下: f[i].data=wi,f[i].lchild=f[i].rchild=0,i=1,2,…,n。

#include

#include

#include

#include

using

namespace std;

char ans[

2010]=

"";int sum=0;

struct tree

a[2010];

struct output

c[2010];

int b[

2010];

//a中位址

bool

cmp(

int x,

int y)

bool

cmpzm

(output x,output y)

void

print

(int x,

int dep)

//中序遍歷輸出

if(a[x]

.l>0)

if(a[x]

.r>0)

return;}

intmain()

print

(n+n-1,

0);sort

(c+1

,c+1

+sum,cmpzm)

;//字典序排序

for(i=

1;i<=sum;i++

)printf

("%c:%s\n"

,c[i]

.z,c[i]

.ans)

,answer+

=strlen

(c[i]

.ans)

*c[i]

.s;//求帶權路徑長度

printf

("%d\n"

,answer)

;return0;

}

樹 哈夫曼樹 二

樹 哈夫曼樹 二 time limit 1000ms memory limit 65536k total submit 47 accepted 30 description 有n n 26 個帶權結點,從a開始的n個字母分別表示這n個結點,他們分別代n個權值,試以它們為葉子結點構造一棵哈夫曼樹 請按...

哈夫曼樹,赫夫曼樹

參考 赫夫曼樹,別名 哈夫曼樹 最優樹 以及 最優二叉樹 當用 n 個結點 這些結點都作為葉子結點且都有各自的權值 試圖構建一棵樹時,如果構建的這棵樹的帶權路徑長度最小,稱這棵樹為 最優二叉樹 有時也叫 赫夫曼樹 或者 哈夫曼樹 構建哈夫曼樹 在 n 個權值中選出兩個最小的權值,對應的兩個結點組成乙...

哈夫曼樹 牛客 哈夫曼樹

哈夫曼樹,第一行輸入乙個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。輸入有多組資料。每組第一行輸入乙個數n,接著輸入n個葉節點 葉節點權值不超過100,2 n 1000 輸出權值。示例1 5 1 ...