Python描述數據結構學習之哈夫曼樹篇
前言
本篇章主要介紹哈夫曼樹及哈夫曼編碼,包括哈夫曼樹的一些基本概念、構造、代碼實現以及哈夫曼編碼,并用Python實現。
1. 基本概念
哈夫曼樹

其中,
帶權路徑長度是帶權結點和根結點之間的路徑長度與該結點的權值的乘積。有關帶權結點、路徑長度的概念請參閱這篇博客。
對于含有
2. 構造過程及實現
給定
比如

代碼實現:
class HuffmanTreeNode(object): def __init__(self): self.data = '#' self.weight = -1 self.parent = None self.lchild = None self.rchild = None class HuffmanTree(object): def __init__(self, data_list): self.nodes = [] # 按權重從大到小進行排列 for val in data_list: newnode = HuffmanTreeNode() newnode.data = val[0] newnode.weight = val[1] self.nodes.append(newnode) self.nodes = sorted(self.nodes, key=lambda node: node.weight, reverse=True) print([(node.data, node.weight) for node in self.nodes]) def CreateHuffmanTree(self): # 這里注意區(qū)分 # TreeNode = self.nodes[:] 變量TreeNode, 這個相當于深拷貝, TreeNode變化不影響nodes # TreeNode = self.nodes 指針TreeNode與nodes共享一個地址, 相當于淺拷貝, TreeNode變化會影響nodes TreeNode = self.nodes[:] if len(TreeNode) > 0: while len(TreeNode) > 1: letfTreeNode = TreeNode.pop() rightTreeNode = TreeNode.pop() newNode = HuffmanTreeNode() newNode.lchild = letfTreeNode newNode.rchild = rightTreeNode newNode.weight = letfTreeNode.weight + rightTreeNode.weight letfTreeNode.parent = newNode rightTreeNode.parent = newNode self.InsertTreeNode(TreeNode, newNode) return TreeNode[0] def InsertTreeNode(self, TreeNode, newNode): length = len(TreeNode) if length > 0: temp = length - 1 while temp >= 0: if newNode.weight < TreeNode[temp].weight: TreeNode.insert(temp+1, newNode) return True temp -= 1 TreeNode.insert(0, newNode)
3. 哈夫曼編碼
在數據通信時,假如我們要發(fā)送
| A | B | C | D | E | F | G | |
|---|---|---|---|---|---|---|---|
| 固定長度編碼 | 000 | 001 | 010 | 011 | 100 | 101 | 110 |
| 可變長度編碼 | 0 | 1 | 01 | 10 | 11 | 101 | 110 |
報文最短可以引申到二叉樹路徑最短,即構造前綴編碼的實質就是構造一棵哈夫曼樹,通過這種形式獲得的二進制編碼稱為哈夫曼編碼。這里的權值就是報文中字符出現的概率,出現概率越高的字符我們用越短的字符表示。
以下表中的字符及其出現的概率為例來實現哈夫曼編碼:
| 字符 | A | B | C | D | E | F | G | H |
|---|---|---|---|---|---|---|---|---|
| 出現概率 | 0.01 | 0.43 | 0.15 | 0.02 | 0.03 | 0.21 | 0.07 | 0.08 |
| 哈夫曼編碼 | 101010 | 0 | 110 | 101011 | 10100 | 111 | 1011 | 100 |

代碼實現就是在哈夫曼樹的基礎上加一個編碼的函數:
def HuffmanEncode(self, Root):
TreeNode = self.nodes[:]
code_result = []
for index in range(len(TreeNode)):
temp = TreeNode[index]
code_leaf = [temp.data]
code = ''
while temp is not Root:
if temp.parent.lchild is temp:
# 左分支
code = '0' + code
else:
# 右分支
code = '1' + code
temp = temp.parent
code_leaf.append(code)
code_result.append(code_leaf)
return code_result
測試結果如下:
if __name__ == '__main__':
tree_obj = HuffmanTree([('A', 0.01), ('B', 0.43), ('C', 0.15), ('D', 0.02), ('E', 0.03), ('F', 0.21), ('G', 0.07), ('H', 0.08)])
huf_tree = tree_obj.CreateHuffmanTree()
huf_code = tree_obj.HuffmanEncode(huf_tree)
for index in range(len(huf_code)):
print('{0}: {1}'.format(huf_code[index][0], huf_code[index][1]))

總結
到此這篇關于Python描述數據結構學習之哈夫曼樹篇的文章就介紹到這了,更多相關Python數據結構之哈夫曼樹內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python監(jiān)控進程狀態(tài),記錄重啟時間及進程號的實例
今天小編就為大家分享一篇python監(jiān)控進程狀態(tài),記錄重啟時間及進程號的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07
將tf.batch_matmul替換成tf.matmul的實現
這篇文章主要介紹了將tf.batch_matmul替換成tf.matmul的實現,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
Python訪問本地deepseek示例【含deepseek本地部署】
這篇文章主要介紹了Python訪問本地deepseek功能,結合實例形式分析了使用Ollama本地部署deepseek以及python訪問本地deepseek的過程,需要的朋友可以參考下2018-06-06
淺談tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意點
這篇文章主要介紹了淺談tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意點,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06
windows 10下安裝搭建django1.10.3和Apache2.4的方法
最近發(fā)現很多教程都是在linux上搭建,windows上似乎天生不太適合,但是我還是愿意試試這個坑。下面這篇文章主要給大家介紹了在windows 10系統(tǒng)下安裝搭建django1.10.3和Apache2.4的方法,需要的朋友可以參考借鑒,下面來一起看看吧。2017-04-04

