如何在 python 中打印哈夫曼树的叶节点值?

问题描述 投票:0回答:0

我正在尝试用叶节点的值打印霍夫曼树,这些叶节点是字母。然而,结果永远是关键,而不是数据本身。我要改变什么?

class PriorityQueue :
  def __init__(self) :
    self.q = []

  def enqueue(self, item) :
    self.q.append(item)
    self.q.sort(key=lambda x: x.key)

  def dequeue(self) :
    if len(self.q) == 0:
      return None
    return self.q.pop(0)

  def size(self):
    return len(self.q)

  def print(self) :
    for item in self.q:
      print("{:^10s} | {:^10d}".format(item.data, item.key))

class Node:
  def __init__(self, key, data=None):
    self.key = key
    self.data = data
    self.leftChild = None
    self.rightChild = None

  def setChildren(self, left, right) :
    self.leftChild = left
    self.rightChild = right
  
  def display(self):
        lines, *_ = self._display_aux()
        for line in lines:
            print(line)
  def _display_aux(self):
        if self.rightChild is None and self.leftChild is None:
            line = '%s' % self.key
            width = len(line)
            height = 1
            middle = width // 2
            return [line], width, height, middle

        if self.leftChild is None:
            lines, n, p, x = self.rightChild._display_aux()
            if self.data is not None:
              s = '%s' % f'{self.data}'
            else:
              s = '%s' % self.key
            u = len(s)
            first_line = (x + 1) * ' ' + (n - x - 1) * '_' + s
            second_line = x * ' ' + '/' + (n - x - 1 + u) * ' '
            shifted_lines = [line + u * ' ' for line in lines]
            return [first_line, second_line] + shifted_lines, n + u, p + 2, n + u // 2

        if self.rightChild is None:
            lines, n, p, x = self.leftChild._display_aux()
            u = len(s)
            first_line = s + x * '_' + (n - x) * ' '
            second_line = (u + x) * ' ' + '\\' + (n - x - 1) * ' '
            shifted_lines = [u * ' ' + line for line in lines]
            return [first_line, second_line] + shifted_lines, n + u, p + 2, u // 2

        right, n, p, x = self.rightChild._display_aux()
        left, m, q, y = self.leftChild._display_aux()
        if self.data is not None:
              s = '%s' % self.data
        else:
              s = '%s' % self.key
        u = len(s)
        first_line = (x + 1) * ' ' + (n - x - 1) * '_' + s + y * '_' + (m - y) * ' '
        second_line = x * ' ' + '/' +(n - x - 1 + u + y) * ' ' + '\\' + (m - y - 1) * ' '
        if p < q:
            right += [n * ' '] * (q - p)
        elif q < p:
            left += [m * ' '] * (p - q)
        zipped_lines = zip(right, left)
        lines = [first_line, second_line] + [a + u * ' ' + b for a, b in zipped_lines]
        return lines, n + m + u, max(p, q) + 2, n + u // 2

class Huffman :
  def __init__(self, str):
    self.str = str
    self.freqTable = {}
    self.conversionTable = {}
    self.treeRoot = None

  def createPriorityQueue(self, str) :
    for char in str:
      if char in self.freqTable:
        self.freqTable[char] += 1
      else:
        self.freqTable[char] = 1
        
        q = PriorityQueue()
        for char, freq in self.freqTable.items():
            node = Node(freq, char)
            q.enqueue(node)
    print("FREQUENCY TABLE")
    print("-----------+----------")
    print("Character  | Frequency")
    print("-----------+----------")
    q.print()
    print("-----------+----------")

  def createHuffmanTree(self) :
    q = PriorityQueue()
    for char, freq in self.freqTable.items():
      node = Node(freq, char)
      q.enqueue(node)

    while q.size() > 1:
      left = q.dequeue()
      right = q.dequeue()
      parent = Node(left.key + right.key)
      parent.setChildren(left, right)
      q.enqueue(parent)

    self.treeRoot = q.dequeue()
    print("HUFFMAN TREE:")
    self.treeRoot.display()

  def createConversionTable(self, node, code='') :
    if node.leftChild is None and node.rightChild is None:
        self.conversionTable[node.data] = code    
        if len(self.conversionTable.items()) == len(self.freqTable.items()):
          print("CONVERSION TABLE")
          print("-----------+----------")
          print("{:^10} | {:^10}".format('Character', 'Code'))
          print("-----------+----------")
          for char, code in self.conversionTable.items():
            print("{:^10} | {:^10}".format(char, code))
          print("-----------+----------")
          print()    
    else:
        self.createConversionTable(node.rightChild, code + '0')
        self.createConversionTable(node.leftChild, code + '1')
        
  def convertString(self, str) : 
    print("HUFFMAN'S CODE")
    print("original: ",str)
    print("encoded:")
    huffman_code = ""
    for i, char in enumerate(str):
      if i % 5 == 0:
        print("")
      huffman_code = huffman_code + self.conversionTable[char]
      print("{:<10}".format(self.conversionTable[char]), end=' ')
    print("")
    return huffman_code
def main() :
  str = input("Enter string: ")
  str = str.lower()

  huffman = Huffman(str)
  huffman.createPriorityQueue(huffman.str)
  huffman.createHuffmanTree()
  huffman.createConversionTable(huffman.treeRoot)
  huffman_code = huffman.convertString(str)
if __name__ == "__main__" :
  main() 

我尝试在 _display_aux 函数中将 self.key 更改为 self.data,但仍然显示数字而不是字母。这也导致其他节点的输出为“无”

输入:黎明时分进攻 期望的输出: [1]: https://i.stack.imgur.com/HgesH.png
我的输出: [2]: https://i.stack.imgur.com/yiYTR.png

python huffman-code
© www.soinside.com 2019 - 2024. All rights reserved.