欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python完成哈夫曼樹(shù)編碼過(guò)程及原理詳解

 更新時(shí)間:2019年07月29日 08:52:53   作者:TomHawk  
這篇文章主要介紹了Python完成哈夫曼樹(shù)編碼過(guò)程及原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

哈夫曼樹(shù)原理

秉著能不寫(xiě)就不寫(xiě)的理念,關(guān)于哈夫曼樹(shù)的原理及其構(gòu)建,還是貼一篇博客吧。

http://www.dbjr.com.cn/article/97396.htm

其大概流程

哈夫曼編碼代碼

# 樹(shù)節(jié)點(diǎn)類構(gòu)建
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)建樹(shù)節(jié)點(diǎn)隊(duì)列函數(shù)
def creatnodeQ(codes):
  q = []
  for code in codes:
    q.append(TreeNode(code))
  return q
# 為隊(duì)列添加節(jié)點(diǎn)元素,并保證優(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é)點(diǎn)隊(duì)列類定義
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)
# 各個(gè)字符在字符串中出現(xiàn)的次數(shù),即計(jì)算優(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)建哈夫曼樹(shù)
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 = {}
# 由哈夫曼樹(shù)得到哈夫曼編碼表
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)

接下來(lái)就是一段一段分析代碼

1.樹(shù)結(jié)點(diǎn)類的構(gòu)建:

共有5個(gè)屬性:結(jié)點(diǎn)的值,結(jié)點(diǎn)的優(yōu)先度,結(jié)點(diǎn)的左子結(jié)點(diǎn),結(jié)點(diǎn)的右子結(jié)點(diǎn),結(jié)點(diǎn)值的編碼(這個(gè)沒(méi)有什么好說(shuō)的,這些屬性都是被需要的)

2.創(chuàng)建樹(shù)結(jié)點(diǎn)隊(duì)列函數(shù):

對(duì)于所有的字母結(jié)點(diǎn),我們將其組成一個(gè)隊(duì)列,這里使用list列表來(lái)完成隊(duì)列的功能。將所有樹(shù)節(jié)點(diǎn)夠放進(jìn)列表中,當(dāng)然傳進(jìn)來(lái)的是按優(yōu)先度從小到大已排序的元素列表

3.為隊(duì)列添加節(jié)點(diǎn)元素,并保證優(yōu)先度從大到小排列:

當(dāng)有新生成的結(jié)點(diǎn)時(shí),需將其插入列表,并放在合適位置,使隊(duì)列依然時(shí)按優(yōu)先度從小打到排列的。

4.結(jié)點(diǎn)隊(duì)列類定義:

創(chuàng)建類初始化時(shí)需要傳進(jìn)去的是一個(gè)列表,列表中的每個(gè)元素是由字母與優(yōu)先度組成的元組。元組第一個(gè)元素是字母,第二個(gè)元素是優(yōu)先度(即在文本中出現(xiàn)的次數(shù))

類初始化化時(shí),調(diào)用“創(chuàng)建樹(shù)結(jié)點(diǎn)隊(duì)列函數(shù)”,隊(duì)列中的每個(gè)元素都是一個(gè)樹(shù)結(jié)點(diǎn)。

類中還包含一個(gè)隊(duì)列規(guī)模屬性以及另外兩個(gè)操作函數(shù):添加結(jié)點(diǎn)函數(shù)和彈出結(jié)點(diǎn)函數(shù)。

添加結(jié)點(diǎn)函數(shù)直接調(diào)用之前定義的函數(shù)即可,輸入的參數(shù)為隊(duì)列和新結(jié)點(diǎn),并且隊(duì)列規(guī)模加一

彈出第一個(gè)元素則直接調(diào)用列表的pop(0)函數(shù),同時(shí)隊(duì)列規(guī)模減一

5.計(jì)算文本中個(gè)字母的優(yōu)先度,即出現(xiàn)的次數(shù):

定義一個(gè)字典,遍歷文本中的每一個(gè)字母,若字母不在字典里說(shuō)明是第一次出現(xiàn),則定義該字母為鍵,另鍵值為1,若在字典里有,則只需將相應(yīng)的鍵值加一。 遍歷后就得到了每個(gè)字母出現(xiàn)的次數(shù)。

6.由哈夫曼樹(shù)得到編碼表:

這里定義了兩個(gè)全局字典,用于存放字母編碼,一個(gè)字典用于編碼,另一個(gè)字典用于解碼,這樣程序操作起來(lái)比較方便。

這里主要就是遍歷,運(yùn)用的是二叉樹(shù)的中序遍歷。如果明白中序遍歷的化,就能看懂這里的代碼,每遞歸到深一層的時(shí)候,就在后面多加一個(gè)‘0'(左子樹(shù))或‘1'(右子樹(shù))。

中序遍歷我在上一篇博客中講的還算可以吧,不懂的可以參考一下,否則就可以略過(guò)這一段。

這一段是哈夫曼編碼的關(guān)鍵,也是難點(diǎn),希望能夠好好理解一下,也是對(duì)遞歸的一個(gè)理解。這一點(diǎn)沒(méi)問(wèn)題的話,我覺(jué)得哈夫曼樹(shù)真的挺簡(jiǎn)單的?。?!

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

這兩段我就不詳細(xì)說(shuō)了,應(yīng)為已經(jīng)有編碼與解碼的字典了,所以對(duì)應(yīng)每一個(gè)字母直接在字典里找就好了,而且字典的尋找速度還是相當(dāng)快的。

差不多了,例子就不舉了,確實(shí)哈夫曼樹(shù)比之前的什么八皇后問(wèn)題還有KMP問(wèn)題簡(jiǎn)單多了。

最后向Huffman大神致敬,祝各位學(xué)有所成。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 使用Python實(shí)現(xiàn)多功能課堂點(diǎn)名器與抽簽工具

    使用Python實(shí)現(xiàn)多功能課堂點(diǎn)名器與抽簽工具

    這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)多功能課堂點(diǎn)名器,也可以用作抽簽工具,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • Python自動(dòng)掃描出微信不是好友名單的方法

    Python自動(dòng)掃描出微信不是好友名單的方法

    很多人想要清楚已經(jīng)被刪除的好友名單。面對(duì)龐大的好友數(shù)量想要清除談何容易,本文主要介紹了Python自動(dòng)掃描出微信不是好友名單的方法,感興趣的可以了解一下
    2021-05-05
  • Python函數(shù)參數(shù)匹配模型通用規(guī)則keyword-only參數(shù)詳解

    Python函數(shù)參數(shù)匹配模型通用規(guī)則keyword-only參數(shù)詳解

    Python3對(duì)函數(shù)參數(shù)的排序規(guī)則更加通用化了,即Python3 keyword-only參數(shù),該參數(shù)即為必須只按照關(guān)鍵字傳遞而不會(huì)有一個(gè)位置參數(shù)來(lái)填充的參數(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)

    下面小編就為大家分享一篇詳談Python3 操作系統(tǒng)與路徑 模塊(os / os.path / pathlib),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • Pycharm運(yùn)行時(shí)總是跳出Python?Console問(wèn)題

    Pycharm運(yùn)行時(shí)總是跳出Python?Console問(wèn)題

    這篇文章主要介紹了Pycharm運(yùn)行時(shí)總是跳出Python?Console問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • python爬蟲(chóng)實(shí)戰(zhàn)之最簡(jiǎn)單的網(wǎng)頁(yè)爬蟲(chóng)教程

    python爬蟲(chóng)實(shí)戰(zhàn)之最簡(jiǎn)單的網(wǎng)頁(yè)爬蟲(chóng)教程

    在我們?nèi)粘I暇W(wǎng)瀏覽網(wǎng)頁(yè)的時(shí)候,經(jīng)常會(huì)看到一些好看的圖片,我們就希望把這些圖片保存下載,或者用戶用來(lái)做桌面壁紙,或者用來(lái)做設(shè)計(jì)的素材。下面這篇文章就來(lái)給大家介紹了關(guān)于利用python實(shí)現(xiàn)最簡(jiǎn)單的網(wǎng)頁(yè)爬蟲(chóng)的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-08-08
  • python圖的深度優(yōu)先和廣度優(yōu)先算法實(shí)例分析

    python圖的深度優(yōu)先和廣度優(yōu)先算法實(shí)例分析

    這篇文章主要介紹了python圖的深度優(yōu)先和廣度優(yōu)先算法,結(jié)合實(shí)例形式分析了圖的深度優(yōu)先算法與廣度優(yōu)先算法相關(guān)概念、原理、實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2019-10-10
  • Python中的正則表達(dá)式與JSON數(shù)據(jù)交換格式

    Python中的正則表達(dá)式與JSON數(shù)據(jù)交換格式

    正則表達(dá)式 是一個(gè)特殊的字符序列,一個(gè)字符串是否與我們所設(shè)定的這樣的字符序列,相匹配快速檢索文本、實(shí)現(xiàn)替換文本的操作。這篇文章主要介紹了Python中的正則表達(dá)式與JSON ,需要的朋友可以參考下
    2019-07-07
  • Python中的rjust()方法使用詳解

    Python中的rjust()方法使用詳解

    這篇文章主要介紹了Python中的rjust()方法使用詳解,是Python學(xué)習(xí)入門中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-05-05
  • Django框架ORM數(shù)據(jù)庫(kù)操作實(shí)例詳解

    Django框架ORM數(shù)據(jù)庫(kù)操作實(shí)例詳解

    這篇文章主要介紹了Django框架ORM數(shù)據(jù)庫(kù)操作,結(jié)合實(shí)例形式詳細(xì)分析了Django框架ORM數(shù)據(jù)庫(kù)基本增刪改查與相關(guān)函數(shù)使用技巧,需要的朋友可以參考下
    2019-11-11

最新評(píng)論