Python完成哈夫曼樹編碼過程及原理詳解
哈夫曼樹原理
秉著能不寫就不寫的理念,關于哈夫曼樹的原理及其構建,還是貼一篇博客吧。
http://www.dbjr.com.cn/article/97396.htm
其大概流程

哈夫曼編碼代碼
# 樹節(jié)點類構建
class TreeNode(object):
def __init__(self, data):
self.val = data[0]
self.priority = data[1]
self.leftChild = None
self.rightChild = None
self.code = ""
# 創(chuàng)建樹節(jié)點隊列函數(shù)
def creatnodeQ(codes):
q = []
for code in codes:
q.append(TreeNode(code))
return q
# 為隊列添加節(jié)點元素,并保證優(yōu)先度從大到小排列
def addQ(queue, nodeNew):
if len(queue) == 0:
return [nodeNew]
for i in range(len(queue)):
if queue[i].priority >= nodeNew.priority:
return queue[:i] + [nodeNew] + queue[i:]
return queue + [nodeNew]
# 節(jié)點隊列類定義
class nodeQeuen(object):
def __init__(self, code):
self.que = creatnodeQ(code)
self.size = len(self.que)
def addNode(self,node):
self.que = addQ(self.que, node)
self.size += 1
def popNode(self):
self.size -= 1
return self.que.pop(0)
# 各個字符在字符串中出現(xiàn)的次數(shù),即計算優(yōu)先度
def freChar(string):
d ={}
for c in string:
if not c in d:
d[c] = 1
else:
d[c] += 1
return sorted(d.items(),key=lambda x:x[1])
# 創(chuàng)建哈夫曼樹
def creatHuffmanTree(nodeQ):
while nodeQ.size != 1:
node1 = nodeQ.popNode()
node2 = nodeQ.popNode()
r = TreeNode([None, node1.priority+node2.priority])
r.leftChild = node1
r.rightChild = node2
nodeQ.addNode(r)
return nodeQ.popNode()
codeDic1 = {}
codeDic2 = {}
# 由哈夫曼樹得到哈夫曼編碼表
def HuffmanCodeDic(head, x):
global codeDic, codeList
if head:
HuffmanCodeDic(head.leftChild, x+'0')
head.code += x
if head.val:
codeDic2[head.code] = head.val
codeDic1[head.val] = head.code
HuffmanCodeDic(head.rightChild, x+'1')
# 字符串編碼
def TransEncode(string):
global codeDic1
transcode = ""
for c in string:
transcode += codeDic1[c]
return transcode
# 字符串解碼
def TransDecode(StringCode):
global codeDic2
code = ""
ans = ""
for ch in StringCode:
code += ch
if code in codeDic2:
ans += codeDic2[code]
code = ""
return ans
# 舉例
string = "AAGGDCCCDDDGFBBBFFGGDDDDGGGEFFDDCCCCDDFGAAA"
t = nodeQeuen(freChar(string))
tree = creatHuffmanTree(t)
HuffmanCodeDic(tree, '')
print(codeDic1,codeDic2)
a = TransEncode(string)
print(a)
aa = TransDecode(a)
print(aa)
print(string == aa)
接下來就是一段一段分析代碼
1.樹結點類的構建:
共有5個屬性:結點的值,結點的優(yōu)先度,結點的左子結點,結點的右子結點,結點值的編碼(這個沒有什么好說的,這些屬性都是被需要的)
2.創(chuàng)建樹結點隊列函數(shù):
對于所有的字母結點,我們將其組成一個隊列,這里使用list列表來完成隊列的功能。將所有樹節(jié)點夠放進列表中,當然傳進來的是按優(yōu)先度從小到大已排序的元素列表
3.為隊列添加節(jié)點元素,并保證優(yōu)先度從大到小排列:
當有新生成的結點時,需將其插入列表,并放在合適位置,使隊列依然時按優(yōu)先度從小打到排列的。
4.結點隊列類定義:
創(chuàng)建類初始化時需要傳進去的是一個列表,列表中的每個元素是由字母與優(yōu)先度組成的元組。元組第一個元素是字母,第二個元素是優(yōu)先度(即在文本中出現(xiàn)的次數(shù))
類初始化化時,調用“創(chuàng)建樹結點隊列函數(shù)”,隊列中的每個元素都是一個樹結點。
類中還包含一個隊列規(guī)模屬性以及另外兩個操作函數(shù):添加結點函數(shù)和彈出結點函數(shù)。
添加結點函數(shù)直接調用之前定義的函數(shù)即可,輸入的參數(shù)為隊列和新結點,并且隊列規(guī)模加一
彈出第一個元素則直接調用列表的pop(0)函數(shù),同時隊列規(guī)模減一
5.計算文本中個字母的優(yōu)先度,即出現(xiàn)的次數(shù):
定義一個字典,遍歷文本中的每一個字母,若字母不在字典里說明是第一次出現(xiàn),則定義該字母為鍵,另鍵值為1,若在字典里有,則只需將相應的鍵值加一。 遍歷后就得到了每個字母出現(xiàn)的次數(shù)。
6.由哈夫曼樹得到編碼表:
這里定義了兩個全局字典,用于存放字母編碼,一個字典用于編碼,另一個字典用于解碼,這樣程序操作起來比較方便。
這里主要就是遍歷,運用的是二叉樹的中序遍歷。如果明白中序遍歷的化,就能看懂這里的代碼,每遞歸到深一層的時候,就在后面多加一個‘0'(左子樹)或‘1'(右子樹)。
中序遍歷我在上一篇博客中講的還算可以吧,不懂的可以參考一下,否則就可以略過這一段。
這一段是哈夫曼編碼的關鍵,也是難點,希望能夠好好理解一下,也是對遞歸的一個理解。這一點沒問題的話,我覺得哈夫曼樹真的挺簡單的!??!
7.字符串編碼,字符串解碼:
這兩段我就不詳細說了,應為已經有編碼與解碼的字典了,所以對應每一個字母直接在字典里找就好了,而且字典的尋找速度還是相當快的。
差不多了,例子就不舉了,確實哈夫曼樹比之前的什么八皇后問題還有KMP問題簡單多了。
最后向Huffman大神致敬,祝各位學有所成。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Python函數(shù)參數(shù)匹配模型通用規(guī)則keyword-only參數(shù)詳解
Python3對函數(shù)參數(shù)的排序規(guī)則更加通用化了,即Python3 keyword-only參數(shù),該參數(shù)即為必須只按照關鍵字傳遞而不會有一個位置參數(shù)來填充的參數(shù)。這篇文章主要介紹了Python函數(shù)參數(shù)匹配模型通用規(guī)則keyword-only參數(shù),需要的朋友可以參考下2019-06-06
詳談Python3 操作系統(tǒng)與路徑 模塊(os / os.path / pathlib)
下面小編就為大家分享一篇詳談Python3 操作系統(tǒng)與路徑 模塊(os / os.path / pathlib),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04
Pycharm運行時總是跳出Python?Console問題
這篇文章主要介紹了Pycharm運行時總是跳出Python?Console問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
python圖的深度優(yōu)先和廣度優(yōu)先算法實例分析
這篇文章主要介紹了python圖的深度優(yōu)先和廣度優(yōu)先算法,結合實例形式分析了圖的深度優(yōu)先算法與廣度優(yōu)先算法相關概念、原理、實現(xiàn)技巧與操作注意事項,需要的朋友可以參考下2019-10-10
Python中的正則表達式與JSON數(shù)據(jù)交換格式
正則表達式 是一個特殊的字符序列,一個字符串是否與我們所設定的這樣的字符序列,相匹配快速檢索文本、實現(xiàn)替換文本的操作。這篇文章主要介紹了Python中的正則表達式與JSON ,需要的朋友可以參考下2019-07-07

