从Huffman树Minheap中弹出/删除节点

Popping/deleting nodes from a Huffman Tree Minheap

本文关键字:删除 节点 Huffman Minheap      更新时间:2023-10-16

我在从Huffman树中正确弹出时遇到问题。现在我正在创建一个基于minheap的Huffman树,我想做以下事情:

如果我们假设A和B是两个不同的子树,我会说,如果A的频率小于B的频率,A将首先弹出如果它们的频率相同,那么我会在A的任何叶节点中找到ASCII值中最小的字符。然后我会看看A中最小的字符叶节点是否比B的任何叶节点都小。如果是,我会在B之前弹出A。如果不是,我会弹出B。<-这就是我遇到的问题。

例如:

假设我输入:

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

进入我的霍夫曼树。然后我的树会是这样的:

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

下面是我尝试跳出我的Huffman 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),这将比您正在进行的swap可读性高得多。然而,在heapDown中交换是低效的:你应该做的是抓住要放在临时位置的元素,然后筛选孩子,直到你找到放元素的地方,然后把它放在那里。

如果您实现了运算符<用于HuffmanNode。在任何情况下,你做的比较都比必要的要多;你真正想做的是(省略了很多细节):

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。所以你在慢慢但无情地泄露记忆。