這個程式包括
①通過輸入建立赫夫曼樹(哈夫曼樹)
②輸入一串字串,能得到其赫夫曼編碼,輸入一串赫夫曼編碼,也能得到其原始字串,有能實現這兩個功能的兩個函式
思路是下面這個博主的,在此表示感謝:
noj-哈夫曼編/解碼器
原題目:
不過為了以後複習時看得懂,我修改了輸入方式:
不過由於中間步驟不同,最後輸出的編碼序列和其他演算法可能有不同,是由於同編碼的赫夫曼樹不止有一棵,如果兩個節點權值相同,兩個的左右位置可以交換
上學期寫這個實驗的時候我用的是指標*lch,*rch,非常費事,**也不知道哪去了,所以借用那個博主的思路直接使用順序結構構造樹
typedef
struct
huffnode;
//單個的樹節點
typedef
struct
hufftree;
先說明主函式內容,理解整體思路,再分條進入看每個功能如何實現
int
main()
,i,nodenum;
//a儲存字串編碼後的01序列,i用來計數,nodenum是字元數目,a[0]儲存內容長度
char b[
101]=;
//b用來儲存01序列翻譯成的字串,b[0]儲存內容長度
nodenum=
input
(&t)
;//把字元及其權值輸入到樹中,同時返回字元數(t->num總結點數)
buildtree
(&t)
;//建樹
code
(&t,a,nodenum)
;//給字串編碼(字串在這個函式中讀取)
encode
(&t,a,b)
;//將a中的編碼翻譯成b中的字元
for(i=
1;i<=a[0]
;i++
)//輸出a中的編碼,同時注意:a[0]、b[0]儲存的都是內容長度,所以從a[1]、b[1]開始
cout<
for(i=
1;i<=b[0]
;i++
)//輸出b中的編碼
return0;
}
輸入:按提示輸入(主函式input,乙個子函式initnode)
int
input
(hufftree *t)
return num;
//最後返回字元的數量
}
void
initnode
(huffnode *node)
建樹(主函式buildtree,兩個子函式weightsum和smallest(不包括initnode))
void
buildtree
(hufftree *t)
t->root=t-
>num;
//當從上面那個while迴圈出來之後,t->num就是最後乙個新建的節點,而它就是根節點。
//由此可見,順序儲存且赫夫曼樹,根節點最後才確定
}
int
weightsum
(hufftree *t)
//就是乙個乙個累加權值
return weightsum;
}
int
smallest
(hufftree *t,
int weightsum)
if(min>t-
>tree[i]
.weight)
//這兩步就是一步一步篩選出權值最小的節點}if
(min==weightsum)
//但是如果此時得到的權值為所有字元權值之和,說明只剩乙個根節點還沒visited了
//那不就是樹建完了嗎?於是返回0,來跳出buildtree函式中的迴圈
else
//如果不是上述情況,那rec記錄的就是權值最小的節點了
}
編碼
呼叫了strlen,要include
void
code
(hufftree *t,
int a[
2001],
int nodenum)
}//下面的原理就是從樹中某個字元節點出發,逐個找它的雙親節點,因此是逆序的
while
(t->tree[position]
.parent)
//當還沒到根節點(根節點的parent是0)
else
//不然就是1
alength++
; position=t-
>tree[position]
.parent;
//看它的雙親節點編碼如何}}
a[0]=alength-1;
//最後一步沒有下一步,卻仍然搞了alength++,所以真實長度是alength-1
reverse
(a);
//最後a是逆序的,因此為了方便起見,把a逆回來,就正序了
}
void
reverse
(int a[
2001])
}
解碼
想象乙個虛擬指標,開始指向根節點,根據赫夫曼編碼每一位的0或1,決定下一步指到它的左孩子還是右孩子.直到指向某個字元,把這個字元輸入到b中,然後讓這個虛擬指標返回根節點,即可
void
encode
(hufftree *t,
int a[
2001],
char b[
101])}
else
//解釋同上,不過注意,if(t->tree[position].rch那步也可以為lch,只要表達出到了底部的意思即可}}
b[0]=blength;
//出迴圈,b內容的長度blength
}
赫夫曼樹 樹
在資料膨脹,資訊 的今天,資料壓縮的意義不言而喻。談到資料壓縮,就不能 不提赫夫曼編碼,赫夫曼編碼是首個使用的壓縮編碼方案,即使在今天的知名壓縮演算法裡,依然可以見到赫夫曼編碼的影子。另外,在資料通訊中,用二進位製給每個字元進行編碼時不得不面對乙個問題是如何使電文總長最短且不產生二義性。根據字元出現...
樹 赫夫曼樹
幾個概念 wpl最小的就是赫夫曼樹 赫夫曼樹的建立 將數列 轉成一顆赫夫曼樹的過程 將數列元素從小到大排序 取出最小的兩個元素,生成一棵新的二叉樹,取出的兩個元素作為新二叉樹的子節點 一般權重小的作為子節點 根節點的權重為子節點權重之和 將處理過的兩個元素從列表中刪除,將新的根節點加入列表 重複1 ...
哈夫曼樹,赫夫曼樹
參考 赫夫曼樹,別名 哈夫曼樹 最優樹 以及 最優二叉樹 當用 n 個結點 這些結點都作為葉子結點且都有各自的權值 試圖構建一棵樹時,如果構建的這棵樹的帶權路徑長度最小,稱這棵樹為 最優二叉樹 有時也叫 赫夫曼樹 或者 哈夫曼樹 構建哈夫曼樹 在 n 個權值中選出兩個最小的權值,對應的兩個結點組成乙...