Python---哈夫曼樹---Huffman Tree

來源:互聯網
上載者:User

標籤:優先   http   文本   not   構建   天才   添加節點   沒有   tom   

 今天要講的是天才哈夫曼的哈夫曼編碼,這是樹形資料結構的一個典型應用。

!!!敲黑板!!!哈夫曼樹的構建以及編碼方式將是我們的學習重點。

老方式,代碼+解釋,手把手教你Python完成哈夫曼編碼的全過程。、

 

首先,我先假設你已經有了二叉樹的相關知識,主要就是概念和遍曆方式這些點。如果沒有這些知識儲備,可能理解起來會比較困難。

好了,廢話不多說。

 

哈夫曼樹原理

秉著能不寫就不寫的理念,關於哈夫曼樹的原理及其構建,還是貼一篇部落格吧。

http://www.cnblogs.com/mcgrady/p/3329825.html。(這篇部落格關於哈夫曼樹及其編碼的原理講的還行,簡潔易懂,因為哈夫曼樹原理本來就挺簡單的)。

其大概流程

 

 

哈夫曼編碼代碼

 

# 樹節點類構建class TreeNode(object):    def __init__(self, data):        self.val = data[0]        self.priority = data[1]        self.leftChild = None        self.rightChild = None        self.code = ""# 建立樹節點隊列函數def creatnodeQ(codes):    q = []    for code in codes:        q.append(TreeNode(code))    return q# 為隊列添加節點元素,並保證優先度從大到小排列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]# 節點隊列類定義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)# 各個字元在字串中出現的次數,即計算優先度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])# 建立哈夫曼樹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個屬性:結點的值,結點的優先度,結點的左子結點,結點的右子結點,結點值的編碼(這個沒有什麼好說的,這些屬性都是被需要的)

  • 2.建立樹結點隊列函數:

    對於所有的字母結點,我們將其組成一個隊列,這裡使用list列表來完成隊列的功能。將所有樹節點夠放進列表中,當然傳進來的是按優先度從小到大已排序的元素列表

  • 3.為隊列添加節點元素,並保證優先度從大到小排列:

    當有新產生的結點時,需將其插入列表,並放在合適位置,使隊列依然時按優先度從小打到排列的。

  • 4.結點隊列類定義:

    建立類初始化時需要傳進去的是一個列表,列表中的每個元素是由字母與優先度組成的元組。元組第一個元素是字母,第二個元素是優先度(即在文本中出現的次數)

    類初始化化時,調用“建立樹結點隊列函數”,隊列中的每個元素都是一個樹結點。

    類中還包含一個隊列規模屬性以及另外兩個操作函數:添加結點函數和彈出結點函數。

    添加結點函數直接調用之前定義的函數即可,輸入的參數為隊列和新結點,並且隊列規模加一

    彈出第一個元素則直接調用列表的pop(0)函數,同時隊列規模減一

  • 5.計算文本中個字母的優先度,即出現的次數:

    定義一個字典,遍曆文本中的每一個字母,若字母不在字典裡說明是第一次出現,則定義該字母為鍵,另索引值為1,若在字典裡有,則只需將相應的索引值加一。 遍曆後就得到了每個字母出現的次數。

  • 6.由哈夫曼樹得到編碼錶:

    這裡定義了兩個全域字典,用於存放字母編碼,一個字典用於編碼,另一個字典用於解碼,這樣程式操作起來比較方便。

    這裡主要就是遍曆,運用的是二叉樹的中序遍曆。如果明白中序遍曆的化,就能看懂這裡的代碼,每遞迴到深一層的時候,就在後面多加一個‘0’(左子樹)或‘1’(右子樹)。

    中序遍曆我在上一篇部落格中講的還算可以吧,不懂的可以參考一下,否則就可以略過這一段。

    這一段是哈夫曼編碼的關鍵,也是痛點,希望能夠好好理解一下,也是對遞迴的一個理解。這一點沒問題的話,我覺得哈夫曼樹真的挺簡單的!!!

  • 7.字串編碼,字串解碼:

    這兩段我就不詳細說了,應為已經有編碼與解碼的字典了,所以對應每一個字母直接在字典裡找就好了,而且字典的尋找速度還是相當快的。

 

 

差不多了,例子就不舉了,確實哈夫曼樹比之前的什麼八皇后問題還有KMP問題簡單多了。

最後向Huffman大神致敬,祝各位學有所成。 

 

 

  

Python---哈夫曼樹---Huffman Tree

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.