Reputation: 35
Ok I have tried to make the Hauffman Code by my own and I have a problem when I'm trying to print the corresponding code to each letter with a recursive method.
(By this point I already created a BinaryTree and root is not NULL) Each node has a value and if it's a leaf it also has a letter, so I begin going down the tree node by node but it seems that in the recursive method the node just forgot who he was or I don't know, I have tried a lot of things. :S
The recursive method is createCode(Node* actual, string actualCode);
Here's the code:
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
#include <queue>
using namespace std;
#define MAX_VALUE 256
int frequencies[MAX_VALUE] = {0};
struct Node {
int value;
char letter;
struct Node *Left, *Right;
}*root=NULL, *temp, *left_temp, *right_temp;
struct CompareNode : public std::binary_function<Node*, Node*, bool> {
bool operator()(const Node* lhs, const Node* rhs) const {
if (lhs->value == rhs->value)
return lhs->letter > rhs->letter;
else
return lhs->value > rhs->value;
}
};
void createCode(Node* actual,string actualCode) {
if (actual->Left == NULL && actual->Right == NULL) {
cout << "For: " << actual->letter << " is " << actualCode << endl;
}
else {
if (actual->Left) {
createCode(actual->Left, actualCode + "0");
}
if (actual->Right) {
createCode(actual->Right, actualCode + "1");
}
}
}
void createTree() {
priority_queue<Node*, vector<Node*>, CompareNode> que;
for (int x = 0; x < MAX_VALUE; x++) {
if (frequencies[x] > 0) {
temp = new Node;
temp->value = frequencies[x];
temp->letter = char(x);
que.push(temp);
}
}
while (que.size() > 1) {
temp = new Node();
temp->Left = que.top();
que.pop();
temp->Right = que.top();
que.pop();
temp->value = temp->Left->value + temp->Right->value;
temp->letter = NULL;
que.push(temp);
}
root = que.top();
que.pop();
}
void fillArray(int argc, char *argv[]) {
string line;
const char* ptr;
ifstream myFile(argv[argc - 1]);
if (myFile.is_open()) {
while (myFile.good()) {
getline(myFile,line);
if (line.length() != 0) {
ptr = &line.at(0);
while (*ptr != '\0')
++frequencies[*ptr++];
}
}
}
else
cout << "The file could not be open.";
}
int main(int argc, char *argv[]) {
fillArray(argc, argv);
createTree();
createCode(root, "");
return 0;
}
This is the example tree (I tried to post the image but because I'm new I could't):
And here's the output:
For: a is 0
For: is 10
Segmentation fault: 11
Please help :(
Upvotes: 3
Views: 392
Reputation: 183898
You need to initialise the Left
and Right
pointers to NULL
when creating the Node
s you push into the queue:
if (frequencies[x] > 0) {
temp = new Node;
temp->Left = NULL;
temp->Right = NULL;
temp->value = frequencies[x];
temp->letter = char(x);
que.push(temp);
}
Without explicit initialisation, these pointers have indeterminate values, and often not NULL
, thus in createCode
you are dereferencing invalid pointers.
Upvotes: 1