My code stops running until the query "search flower rose" and does not continue to process the rest of the queries in in.txt. I think that the loop is exiting due to some other condition rather than reaching EOF but I am not entirely sure.
The other issue is that nothing is outputting to the out.txt file that I have created. This may be due to the EOF conditions but then again, not entirely sure.
Here is in.txt.
4 28 17
fish
animal
bird
fruit
animal cat 32
fish goldfish 20
animal dog 40
bird blackbird 10
animal bear 10
fruit mango 100
animal alligator 50
animal tiger 4
animal lion 2
fish swordfish 10
animal deer 5
animal cow 15
fish garfish 5
fish catfish 55
fish salmon 40
bird crow 21
bird dove 10
bird flamingo 15
fruit apple 50
fruit banana 50
fruit nectarine 10
fruit coconut 10
fruit peach 40
fruit apricot 30
fruit avocado 20
fruit cherry 100
fruit cranberry 100
animal horse 6
search fruit avocado
search fish tilapia
search animal cow
search bird crow
search bird cow
search animal cat
item_before animal deer
height_balance animal
height_balance bird
height_balance fish
search flower rose
count animal
count fruit
search animal koala
search animal cat
count animal
search fruit mango
What I have tried:
#include <iostream>
#include <string.h>
using namespace std;
FILE *outfile;
class itemNode{
public:
char name [50];
int count;
itemNode *left, *right;
itemNode(){
name[0] = '\0';
count = 0;
left = NULL;
right = NULL;
}
itemNode(char itemName[], int population){
strcpy(name, itemName);
count = population;
left = NULL;
right = NULL;
}
};
class treeNameNode{
public:
char treeName[50];
treeNameNode *left, *right;
itemNode *theTree;
treeNameNode(){
treeName[0] = '\0';
theTree = NULL;
left = NULL;
right = NULL;
}
treeNameNode(char name[]){
strcpy(treeName, name);
theTree = NULL;
left = NULL;
right = NULL;
}
};
treeNameNode* buildNameTree(FILE *infile, int N){
treeNameNode *root = NULL;
char name[50];
for(int i = 0; i < N; i++){
if(fscanf(infile, "%s", name) == EOF){
break;
}
treeNameNode *newNode = new treeNameNode(name);
if(root == NULL){
root = newNode;
}
else{
treeNameNode *temp = root;
treeNameNode *parent = NULL;
while(temp != NULL){
parent = temp;
if(strcmp(name, temp->treeName) > 0){
temp = temp->right;
}
else{
temp = temp->left;
}
}
if(strcmp(name, parent->treeName) > 0){
parent->right = newNode;
}
else{
parent->left = newNode;
}
}
}
return root;
}
treeNameNode* insertNameNode(treeNameNode *root, treeNameNode *newNode){
if(root == NULL){
return newNode;
}
if(strcmp(newNode->treeName, root->treeName) > 0){
if(root->right != NULL){
root->right = insertNameNode(root->right, newNode);
}
else{
root->right = newNode;
}
}
else{
if(root->left != NULL){
root->left = insertNameNode(root->left, newNode);
}
else{
root->left = newNode;
}
}
return root;
}
itemNode* insertItemNode(itemNode *root, itemNode *newNode){
if(root == NULL){
return newNode;
}
if(strcmp(newNode->name, root->name) > 0){
if(root->right != NULL){
root->right = insertItemNode(root->right, newNode);
}
else{
root->right = newNode;
}
}
else{
if(root->left != NULL){
root->left = insertItemNode(root->left, newNode);
}
else{
root->left = newNode;
}
}
return root;
}
void printTreeNames(treeNameNode *root) {
if (root != NULL) {
printTreeNames(root->left);
cout << root->treeName << " ";
fprintf(outfile, "%s ", root->treeName);
printTreeNames(root->right);
}
}
void traverse_itemTree(itemNode *root){
if(root != NULL){
traverse_itemTree(root->left);
cout << root->name << " ";
fprintf(outfile, "%s ", root->name);
traverse_itemTree(root->right);
}
}
void traverse_in_traverse(treeNameNode *root){
if(root != NULL){
traverse_in_traverse(root->left);
cout << "\n***" << root->treeName << "***" << endl;
fprintf(outfile, "\n***%s***", root->treeName);
traverse_itemTree(root->theTree);
traverse_in_traverse(root->right);
}
}
treeNameNode* searchNameNode(treeNameNode *root, char treeName[50]){
if(root == NULL){
return NULL;
}
if(strcmp(root->treeName, treeName) == 0){
return root;
}
else if(strcmp(root->treeName, treeName) > 0){
return searchNameNode(root->left, treeName);
}
else{
return searchNameNode(root->right, treeName);
}
}
itemNode* searchItemNode(itemNode *root, char itemName[50]){
if(root == NULL){
return NULL;
}
if(strcmp(root->name, itemName) == 0){
return root;
}
else if(strcmp(root->name, itemName) > 0){
return searchItemNode(root->left, itemName);
}
else{
return searchItemNode(root->right, itemName);
}
}
void countItems(itemNode *root, int *count){
if(root != NULL){
countItems(root->left, count);
*count += root->count;
countItems(root->right, count);
}
}
void count(treeNameNode *root, char treeName[50]){
int count = 0;
treeNameNode *temp = searchNameNode(root, treeName);
countItems(temp->theTree, &count);
cout << "\n" << treeName << " count " << count << endl;
fprintf(outfile, "\n%s count %d\n", treeName, count);
}
void search(treeNameNode *root, char treeName[50], char itemName[50]){
treeNameNode *tree = searchNameNode(root, treeName);
if(tree == NULL){
cout << "\n" << treeName << " does not exist" << endl;
fprintf(outfile, "\n%s does not exist\n", treeName);
}
itemNode *item = searchItemNode(tree->theTree, itemName);
if(item == NULL){
cout << "\n" << itemName << " not found in " << treeName << endl;
fprintf(outfile, "\n%s not found in %s\n", itemName, treeName);
}
else{
cout << "\n" << item->count << " " << itemName << " found in " << treeName << endl;
}
}
void traverse_before(itemNode *root, char itemName[50], int *count){
if(root != NULL){
traverse_before(root->left, itemName, count);
if(strcmp(root->name, itemName) < 0){
(*count)++;
}
traverse_before(root->right, itemName, count);
}
}
void item_before(treeNameNode *root, char treeName[50], char itemName[50]){
int count = 0;
treeNameNode *tree = searchNameNode(root, treeName);
traverse_before(tree->theTree, itemName, &count);
cout << "\nitem before " << itemName << ": " << count << endl;
fprintf(outfile, "\nitem before %s: %d\n", itemName, count);
}
int height(itemNode *node){
if(node == NULL){
return 0;
}
int left = height(node->left);
int right = height(node->right);
return (left > right) ? left + 1 : right + 1;
}
void height_balance(treeNameNode *root, char treeName[50]){
treeNameNode *tree = searchNameNode(root, treeName);
int leftHeight = height(tree->theTree->left);
int rightHeight = height(tree->theTree->right);
int difference = abs(leftHeight - rightHeight);
if(difference > 1){
cout << "\n" << treeName << ": left height " << leftHeight << ", right height " << rightHeight << ", difference " << difference << ", not balanced" << endl;
fprintf(outfile, "\n%s: left height %d, right height %d, difference %d, not balanced\n", treeName, leftHeight, rightHeight, difference);
}
else{
cout << "\n" << treeName << ": left height " << leftHeight << ", right height " << rightHeight << ", difference " << difference << ", balanced" << endl;
fprintf(outfile, "\n%s: left height %d, right height %d, difference %d, balanced\n", treeName, leftHeight, rightHeight, difference);
}
}
void query(treeNameNode *root, FILE *infile, int Q){
for(int i = 0; i < Q; i++){
char query[50];
char treeName[50];
char itemName[50];
if(fscanf(infile, "%s", query) == EOF){
break;
}
if(strcmp(query, "search") == 0){
if(fscanf(infile, "%s %s", treeName, itemName) == EOF){
break;
}
search(root, treeName, itemName);
}
else if(strcmp(query, "item_before") == 0){
if(fscanf(infile, "%s %s", treeName, itemName) == EOF){
break;
}
item_before(root, treeName, itemName);
}
else if(strcmp(query, "height_balance") == 0){
if(fscanf(infile, "%s", treeName) == EOF){
break;
}
height_balance(root, treeName);
}
else if(strcmp(query, "count") == 0){
if(fscanf(infile, "%s", treeName) == EOF){
break;
}
count(root, treeName);
}
}
}
int main(){
FILE *infile = fopen("in.txt", "r");
outfile = fopen("out.txt", "w");
int N, I, Q;
if(fscanf(infile, "%d %d %d", &N, &I, &Q) == EOF){
return 0;
}
treeNameNode *root = buildNameTree(infile, N);
for(int i = 0; i < I; i++){
char treeName[50], itemName[50];
int population;
if(fscanf(infile, "%s %s %d", treeName, itemName, &population) == EOF){
break;
}
itemNode *newNode = new itemNode(itemName, population);
treeNameNode *tree = searchNameNode(root, treeName);
tree->theTree = insertItemNode(tree->theTree, newNode);
}
printTreeNames(root);
traverse_in_traverse(root);
query(root, infile, Q);
fclose(infile);
fclose(outfile);
}