簡體   English   中英

從霍夫曼樹Minheap中彈出/刪除節點

[英]Popping/deleting nodes from a Huffman Tree Minheap

我無法從霍夫曼樹中正確彈出。 現在,我正在基於minheap創建Huffman樹,我想執行以下操作:

如果我們假設A和B是兩個不同的子樹,我想說如果A的頻率小於B的頻率,則A將首先彈出。 如果它們具有相同的頻率,那么我將在A的任何葉節點中找到ASCII值最小的字符。 然后,我將查看A中最小的字符葉節點是否小於B中任何一個葉節點。 如果是這樣,我會在B之前彈出A。否則,我會彈出B。 <-這就是我遇到的麻煩。

例如:

假設我輸入:

eeffgghh\n (every letter except for \n's frequency which is 1 is 2)

進入我的霍夫曼樹。 然后我的樹看起來像這樣:

        9      
       / \
    5        4    
   / \      / \
  3  h      g  f
 /\
e  \n

以下是我嘗試從我的霍夫曼minheap中彈出的嘗試。 比較兩個字母的頻率是否相同時,我遇到了麻煩。 如果有人可以幫助,那就太好了。 謝謝!

void minHeap::heapDown(int index)
{
  HuffmanNode *t = new HuffmanNode();
  if(arr[index]->getFreq() == arr[left]->getFreq() || arr[index]->getFreq() == arr[right]->getFreq()) //arr is an array of HeapNodes
    {
      if(arr[left]->getLetter() < arr[right]->getLetter())
      {
        t = arr[index]; //equals operator is overloaded for swapping
        arr[index] = arr[left];
        arr[left] = t;
        heapDown(left);
      }
      else
      {
        t = arr[index];
        arr[index] = arr[right];
        arr[right] = t;
        heapDown(right);
      }
    }
    if(arr[index]->getFreq() > arr[left]->getFreq() || arr[index]->getFreq() > arr[right]->getFreq())
    {
      if(arr[left]->getFreq() < arr[right]->getFreq())
      {
        t = arr[index];
        arr[index] = arr[left];
        arr[left] = t;
        heapDown(left);
      }
      else
      {
        t = arr[index];
        arr[index] = arr[right];
        arr[right]  = t;
        heapDown(right);
      }//else
    }//if
}

標准的C ++庫包含堆算法。 除非您不被允許使用它,否則您可能會發現它更容易。

標准C ++庫還包含swap(a,b),它比您正在執行的交換更具可讀性。 但是,在heapDown中交換效率很低:您應該做的就是將要放置在臨時元素中的元素固定下來,然后篩選子元素,直到找到放置元素的位置,然后再將其放置在其中。

如果為HuffmanNode實現operator <,您的代碼也將更具可讀性。 無論如何,您所做的比較多於必要。 您真正想要做的是(省略很多細節):

heapDown(int index, Node* value) {
  int left = 2 * min - 1;  // (where do you do this in your code???)
  // It's not this simple because you have to check if left and right both exist
  min = *array[left] < *array[left + 1] ? left : left + 1;  // 1 comparison
  if (array[min] < to_place) {
    array[index] = array[min];
    heapDown(min, value);
  } else {
     array[index] = value;
  }

您的第一個比較(第三行)是完全錯誤的。 a == b || a == c並不意味着b == c,或者實際上為您提供了有關b和c中哪個較小的任何信息。 通常僅對b和c進行第二次比較會得出錯誤的答案。

最后,您不必在每次調用時都執行new ,但是永遠不要執行delete 因此,您正在緩慢但不可避免地泄漏內存。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM