解壓zip_VBA解壓縮ZIP檔案06——Huffman樹碼錶
阿新 • • 發佈:2021-01-20
技術標籤:解壓zip
Huffman樹創建出來之後,自然需要用到它的碼錶,碼錶的意思就是通過一串bit能夠找到葉子節點,然後這串bit對應的就是葉子節點Key,Huffman樹每個葉子節點都有一串與之對應的bit,而且因為Huffman樹的特殊,某一個短的bit串都不可能會是其他長串的字首,比如下面這個碼錶:
bit | Key |
00 | 8 |
010 | 0 |
011 | 5 |
100 | 6 |
101 | 7 |
1100 | 4 |
1101 | 9 |
1110 | 17 |
11110 | 18 |
111110 | 3 |
111111 | 16 |
如果想檢視自己建立的Huffman樹的碼錶,只需要寫個簡單的遞迴函式打印出來:
Public Sub PrintOut() RPrintOut root, ""End SubPrivate Function RPrintOut(n As CNode, str As String) If n.Weight = 2 Then Debug.Print str, n.Key Exit Function Else RPrintOut n.Left, str & "0" RPrintOut n.Right, str & "1" End IfEnd Function
注意我這裡用來判斷是否是葉子節點的條件If n.Weight = 2 Then,在前面建立的過程介紹過,為了建立方便,每一個初始的節點都設定Weight = 2,然後進行左右子樹的擴充套件,擴充套件的時候節點的Weight-1,只有葉子節點是沒有擴充套件左右子樹的,所以Huffman中只有葉子節點的Weight = 2。
當然這裡也可以去判斷左右子樹是否同時為Nothing。
但我們在解壓資料的時候,是從壓縮資料流中一個一個bit的去讀取的,如果先記錄下碼錶,就需要不停的判斷已讀出的bit串是否出現在碼錶中,需要較多的比較次數。
在Huffman樹這個結構中,完全是沒有那個必要的,需要做的是好好利用Huffman樹:
1、節點n從根節點開始
2、從壓縮資料流中讀取一個bit,如果是0,n指向n.Left,如果是1,n指向n.Right
3、判斷n是否是葉子節點,如果是返回n.Key,否則,重複2-3
邏輯其實挺簡單的,程式碼實現:
'找到葉子節點的Key'從bitIndex位置,逐個讀取cpByte中的Bit,直到葉子節點Function GetLeafKey(cpByte() As Byte, ByRef bitIndex As Long) As Long Dim bValue As Long Dim n As CNode Set n = root 'HuffmanTree裡把葉子節點的Weight設定成了2 Do Until n.Weight = 2 '逐個bit的去h中查詢,到達葉子節點為止 bValue = GetBit(cpByte, bitIndex) bitIndex = bitIndex + 1 '1的時候右 If bValue Then Set n = n.Right Else Set n = n.Left End If Loop GetLeafKey = n.Key Set n = NothingEnd Function
00ZIP是什麼
01實現的功能
02 壓縮過程
03 解壓準備工作
04 解析ZIP檔案結構
05 Huffman樹