I'm new of C++ and I'm making a huffman tree written in c++, and I'm in trouble in generating tree structure. Here is my code:
void Huffman::generateTree() {
std::vector<Node> nodes;
for (auto itr : freq) {
nodes.push_back(*(new Node(itr.first, itr.second)));
}
while (nodes.size() > 1) {
Node::sort(&nodes);
Node leftNode = nodes.back();
nodes.pop_back();
Node rightNode = nodes.back();
nodes.pop_back();
Node newAnode = *new Node();
newAnode.merge(&leftNode,&rightNode);
nodes.push_back(newAnode);
}
root = &nodes.back();
displayTree();
}
It finally combined to one node, but the left node and right node is wrong: (For debug purpose, every node have a random ID when created so that I found problem.)
NODE freq26|id96
|-Left:
NODE freq10|id17
|-Left:
|--ERROR:SELF freq10|id17
|-Right:
NODE freq16|id19
|-Left:
NODE freq10|id17
|-Left:
|--ERROR:SELF freq10|id17
|-Right:
NODE freq16|id19
|-Left:
NODE freq10|id17
|-Left:
|--ERROR:SELF freq10|id17
|-Right:
NODE freq16|id19
...endless loop
Just like the output, start from the first subnode, every nodes' left child node is it self and right node is another node but only two switching each other, and finally looped.
I searched and read several post about this and I know it maybe caused by pop_back
and push_back
elements to vector, the pointer may be point to another element, but how I can resolved it? Is there any way to get the REAL element in vector that not affected by operating vector?
Here are some code of my Node:
//header
class Node {
private:
char value;
int frequency;
Node *left;
Node *right;
String code;
...
class Huffman{
private:
Node * root;
std::map<char,int> freq;// calculated frequency of data
bool generated;
//source
bool Node::sortMethod::operator()(const Node &nodeA, const Node &nodeB) {
return nodeA.getFrequency() > nodeB.getFrequency();//getFrequency(): simply return node's frequency int
}
void Node::sort(std::vector<Node> *nodes) {
std::sort(nodes->begin(), nodes->end(), sortMethod());
}
Node *Node::merge(Node *pLeft, Node *pRight) {
left = pLeft;
right = pRight;
frequency = left->getFrequency() + right->getFrequency();
return this;
}
Everything helpful is welcome, thanks!