假設用於通訊的電文僅由8個字母組成,字母在電文中出現的頻率分別為7、19、2、6、32、3、21、10。試為這8個字母設計哈夫曼編碼。如果用二進位制數表示這8個字母的編碼方案.(請按照左子樹根節點的權小於等於右子樹根節點的權的次序構造)
這道題應該用哈弗曼編碼來做,要設計哈弗曼編碼就要先構造一棵哈弗曼樹。
哈夫曼樹是權大的葉子離根最近的二叉樹,最主要的特點是帶權的二叉樹的路徑長度最小。
具體構造方法:
(1)根據給定的n個權值{w1,w2,…,wn},構造n棵二叉樹的集合f={t1,t2,…,tn},其中每棵二叉樹中均只含乙個權值為wi的根結點,其左、右子樹為空樹;
(2)在f中選取其根結點的權值最小的兩棵二叉樹,分別作為左、右子樹構造一棵新的二叉樹,並置這棵新的二叉樹根結點的權值為其左、右子樹根結點的權值之和;
(3)從f中刪去這兩棵樹,同時加入剛生成的新樹;
(4)重複(2)和(3)兩步,直到f中只含一棵樹為止。
利用哈夫曼樹進行編碼稱為哈夫曼編碼。我們約定在二叉樹中用葉結點表示字元。從根結點到葉子的路徑中,左分支表示「0」,右分支表示「1」,從根結點到葉結點上的路徑分支所組成的字串作為該葉結點字元的編碼。
哈夫曼演算法的實現與實際問題所採用的儲存結構有關。現假設用陣列f來儲存哈夫曼樹,其中第i個陣列元素f[i]是哈夫曼樹中的乙個結點,其位址為i,有3個域,data域存放該結點的權值,lchild域和rchild域分別存放該結點左、右子樹的根結點的位址。在初始狀態下: f[i].data=wi,f[i].lchild=f[i].rchild=0,i=1,2,…,n。
即先構造了n個葉子。在以後每步構造一棵新二叉樹時,都需要對森林中所有二叉樹的根結點進行排序,因此可用陣列a作為排序暫存空間,其中第i個陣列元素a[i]是森林f中第i棵二叉樹的根結點,有2個域,data是根結點所對應的權值,addr是根結點在f中的位址。在初始狀態下:a[i].data=wi,a[i].addr=i,i=1,2,…n。
最後依次輸出就可以了。
type
arr=record
data:integer;
lchild,rchild:integer;
addr:integer;
end;
var i,j,t,n:longint;
s:string;
a,f:array[0..100]of arr;
procedure
sort
(k:longint);
//排序
var i,j:longint;
t:arr;
begin
for i:=1
to k-1
dofor j:=i+1
to k do
if a[i].data>a[j].data then
begin
t:=a[i];a[i]:=a[j];a[j]:=t;
end;
end;
procedure
visit
(k:longint;s:string);
begin
if f[k].data=0
then
exit;
visit(f[k].lchild,s+'0');
inc(i);
if i mod
2=0then
//這樣可以剛好輸出答案
writeln(f[k].data,':',s);
visit(f[k].rchild,s+'1');
end;
begin
readln(n);
for i:=1
to n do
begin
readln(a[i].data);
f[i].data:=a[i].data;
a[i].addr:=i;
end;
t:=n+1;i:=n;
while i>1
dobegin
sort(i);
f[t].data:=a[1].data+a[2].data;
//最小的兩棵樹組成新樹
f[t].lchild:=a[1].addr; //因為排了序,所以a[1]的權值比a[2]小,a[1]作為左子樹
f[t].rchild:=a[2].addr;
//更新a[1]和a[2]的值
a[1].addr:=t;
a[2].data:=a[i].data;
a[2].addr:=a[i].addr;
inc(t);
dec(i);
end;
i:=1;
visit(t-1,s);//輸出
end.
SSL 1407 樹 哈夫曼樹 一
time limit 1000ms memory limit 65536k 假設用於通訊的電文僅由8個字母組成,字母在電文 現的頻率分別為7 19 2 6 32 3 21 10。試為這8個字母設計哈夫曼編碼。如果用二進位制數表示這8個字母的編碼方案 請按照左子樹根節點的權小於等於右子樹根節點的權的次...
哈夫曼樹,赫夫曼樹
參考 赫夫曼樹,別名 哈夫曼樹 最優樹 以及 最優二叉樹 當用 n 個結點 這些結點都作為葉子結點且都有各自的權值 試圖構建一棵樹時,如果構建的這棵樹的帶權路徑長度最小,稱這棵樹為 最優二叉樹 有時也叫 赫夫曼樹 或者 哈夫曼樹 構建哈夫曼樹 在 n 個權值中選出兩個最小的權值,對應的兩個結點組成乙...
哈夫曼樹 牛客 哈夫曼樹
哈夫曼樹,第一行輸入乙個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。輸入有多組資料。每組第一行輸入乙個數n,接著輸入n個葉節點 葉節點權值不超過100,2 n 1000 輸出權值。示例1 5 1 ...