How do I put Hash Tables into a Stack in C++? - c++

I'm trying to make a stack of hash tables with the push and pop functions. I have the push and pop down, but is there a way to modify the stack to put H1 and H2 into Stack One? Currently, my stack holds ints for testing purposes.
Below are all headers and source files. I'd really like a solution for this issue. Thanks.
Stack.h
#ifndef STACK_H
#define STACK_H
#include <string>
using namespace std;
class Stack
{
private:
struct item
{
int value;
item* prev;
};
item* stackPtr;
public:
void Push(int value);
void Pop();
void ReadItem(item* r);
void Print();
Stack(); //called when stack is created
~Stack();//called when stacked item is ended
};
#endif /* STACK_H */
Stack.cpp
#include <iostream>
#include <cstdlib>
#include "Stack.h"
using namespace std;
Stack::Stack()
{
stackPtr = NULL;
}
Stack::~Stack()
{
item* p1; //pointer 1
item* p2; //pointer 2
p1 = stackPtr;
while(p1 != NULL)
{
p2 = p1;
p1 = p1->prev;
p2->prev = NULL;
delete p2;
}
}
void Stack::Push(int value)
{
item* n = new item;
n->value = value;
if(stackPtr == NULL)
{
stackPtr = n;
stackPtr->prev = NULL;
}
else
{
n->prev = stackPtr;
stackPtr = n;
}
}
void Stack::ReadItem(item* r)
{
cout << "value: " << r->value << endl;
cout << "------------------\n";
}
void Stack::Pop()
{
if(stackPtr == NULL)
{
cout << "The stack is empty\n";
}
else
{
item* p = stackPtr;
ReadItem(p);
stackPtr = stackPtr->prev;
p->prev = NULL;
delete p;
}
}
void Stack::Print()
{
item* p = stackPtr;
while(p != NULL)
{
ReadItem(p);
p = p->prev;
}
}
Hashtable.h
#include <cstdlib>
#include <iostream>
#include <string>
#ifndef HASHTABLE_H
#define HASHTABLE_H
class HashTable
{
private:
static const int tableSize = 10;
//everything in the braces are what makes the item
struct obj
{
int name;
obj* next;
};
obj* HASHTBL[tableSize];
public:
HashTable();
//Hash is the function represents where in the hash table
//we will store the key
//take a string stored in variable
int Hash( int key);
void AddObj(int name);
int ItemsinBucket(int index);
void PrintTable();
};
#endif /* HASHTABLE_H */
Hashtable.cpp
#include <cstdlib>
#include <iostream>
#include <string>
#include "HashTable.h"
using namespace std;
//Takes from the HashTable class in HashTable.h
HashTable::HashTable()
{
for(int x = 0; x < tableSize; x++)
{
HASHTBL[x] = new obj;
HASHTBL[x]->name = NULL;
HASHTBL[x]->next = NULL;
}
}
void HashTable::AddObj( int name)
{
int index = Hash(name);
if(HASHTBL[index]->name == NULL)
{
HASHTBL[index]->name = name;
}
else
{
obj* Ptr = HASHTBL[index];
obj* n = new obj;
n->name = name;
n->next = NULL;
while(Ptr->next !=NULL)
{
Ptr = Ptr->next;
}
Ptr->next = n;
}
}
int HashTable::ItemsinBucket(int index)
{
int count = 0;
if (HASHTBL[index]->name == NULL)
{
return count;
}
else
{
count++;
obj* Ptr = HASHTBL[index];
while(Ptr->next != NULL)
{
count++;
Ptr = Ptr->next;
}
}
return count;
}
void HashTable::PrintTable()
{
int number;
for(int x = 0; x< tableSize; x++)
{
number = ItemsinBucket(x);
cout << "------------------------\n";
cout << "index = " << x << endl;
cout << HASHTBL[x]->name << endl;
cout << "The num of items in index = "<< number << endl;
cout << "------------------------\n";
}
}
int HashTable::Hash(int key)
{
//defining HashTable function:
int HashTable = 0;
int index;
//will return integer value...or length of string you pass in
for(int x = 0; x < key-1; x++)
{
HashTable = HashTable + x;
}
//so the hash table will take a number and mod it to return the remainder
//the remainder is the index
index = HashTable % tableSize;
return index;
}
main.cpp
#include <iostream>
#include <cstdlib>
#include "Stack.h"
#include "HashTable.h"
using namespace std;
int main(int argc, char** argv)
{
Stack One;
One.Push(3);
One.Push(0);
One.Push(4);
One.Push(5);
HashTable H1;
H1.AddObj(4);
H1.AddObj(23);
H1.AddObj(200);
H1.AddObj(10);
H1.AddObj(15);
H1.AddObj(42);
H1.AddObj(33);
H1.AddObj(44);
H1.AddObj(55);
H1.AddObj(5);
H1.AddObj(9);
H1.AddObj(90);
HashTable H2;
H2.AddObj(10);
H2.AddObj(90);
H2.AddObj(99);
H2.AddObj(34);
H2.AddObj(88);
H2.AddObj(14);
H2.AddObj(87);
H2.AddObj(18);
H2.AddObj(54);
H2.AddObj(56);
H2.AddObj(6);
H2.AddObj(2);
One.Print();
cout << "\n\n\n";
H1.PrintTable();
/*
cout << "1. Push Stack Element" << endl;
cout << "2. Pop Stack Element" << endl;
cout << "3. Search Hash Table" << endl;
*/
return 0;
}

Related

HashTable Keeps producing segFault. How to properly delete using destructor?

I have a HashTable class. The purpose of this is to practice how to produce Hash Table. My current issue right now is the destructor. I should be seeing on the console, this:
But instead i see this:
I've ran gdb ./app which gives me this:
#include <iostream>
#include "HashTable.h"
using namespace std;
int main(){
HashTable table;
table.initTable();
table.addNode("Software");
table.addNode("Engineering");
table.addNode("Art");
table.addNode("Programming");
table.addNode("Miscellanous");
table.displayByIndex();
return 0;
}
HashTable Header:
#ifndef _HASHTABLE_H_
#define _HASHTABLE_H_
#include <iostream>
#include "Hash.h"
class HashTable{
private:
static const int TABLESIZE = 5;
Hash* head;
public:
HashTable();
~HashTable();
void initTable();
int hashKey(char*);
int quadProbing(int,int);
int hashKeyWithProbing(char*);
bool isEmpty();
void addNode(char*);
void displayByIndex();
void searchByKey(char*);
};#endif
Here it my Hash Table CPP, i included the Constructor/Destructor and init functions. The other functions arent included since i dont utilize the 'new' keyword. If its needed i will include it [hope to make this thread small]
#include "HashTable.h"
#include <cstring>
HashTable::HashTable(){
head = new Hash[TABLESIZE];
}
HashTable::~HashTable(){
Hash* destList = NULL;
for(int i = 0; i< TABLESIZE; i++){
destList = &head[i];
while(destList != NULL){
head = head->getNext();
delete destList;
destList = head;
}
}
head = NULL;
delete [] head;
}
void HashTable::initTable(){
for(int i = 0; i < TABLESIZE; i++){
Hash *traverseHeadArray = &head[i];
traverseHeadArray->setKey("EMPTY");
traverseHeadArray->setNext(NULL);
traverseHeadArray = NULL;
}
}
int HashTable::hashKey(char *tempKey){
//Find the asc value for the string
//add them together
//modules by the total table size
//then return the index (remainder using modules)
//Index is were that key will be stored
int index = 0;
for(int i = 0; i < strlen(tempKey); i++){
index += tempKey[i];
}
return index % TABLESIZE;
}//DONE
int HashTable::quadProbing(int index, int counter){
return (index + counter*counter) % TABLESIZE;
}//DONE
int HashTable::hashKeyWithProbing(char* key){
int index = hashKey(key);
int count = 1;
while(head[index].getKey() != key && head[index].getKey() != "EMPTY"){
index = quadProbing(index, count);
count++;
}
return index;
}//DONE
void HashTable::addNode(char* tempValue){
Hash* newNode = new Hash;
newNode->setKey(tempValue);
newNode->setNext(NULL);
int index = hashKey(tempValue);
int counter = 1;
while(head[index].getKey() != tempValue && head[index].getKey() !="EMPTY")
{
index = quadProbing(index, counter);
counter++;
}
Hash* traverse = &head[index];
if(isEmpty() || traverse->getKey() == "EMPTY"){
traverse->setKey(newNode->getKey());
traverse->setNext(newNode->getNext());
}else{
while(traverse->getNext() != NULL)
traverse = traverse->getNext();
traverse->setNext(newNode);
}
traverse = NULL;
delete newNode;
}
void HashTable::displayByIndex(){
for(int i = 0; i < TABLESIZE; i++){
Hash *traverse = &head[i];
std::cout << "----------------------------------------" << std::endl;
std::cout << "INDEX: " << i << std::endl;
while(traverse != NULL){
std::cout << "Key: " << traverse->getKey() << std::endl;
traverse = traverse->getNext();
}
std::cout << "----------------------------------------" << std::endl;
traverse = NULL;
}
}
bool HashTable::isEmpty(){
return (head == NULL);
}
void HashTable::searchByKey(char* key){
int index = hashKeyWithProbing(key);
if(isEmpty())
std::cout << "Empty Bucket\n";
else{
Hash* traverse = &head[index];
while(traverse != NULL && traverse->getKey() != "EMPTY"){
std::cout << "TOPIC KEY: " << traverse->getKey() << std::endl;
traverse = traverse->getNext();
}
traverse = NULL;
}
}
Here is my Hash Class header and CPP files:
#ifndef _HASH_H_
#define _HASH_H_
class Hash{
private:
char* key;
Hash* next;
public:
Hash();
~Hash();
void setKey(char*);
void setNext(Hash* const);
char* getKey();
Hash* getNext();
};#endif
#include "Hash.h"
#include <iostream>
Hash::Hash(){
key = NULL;
next = NULL;
}
Hash::~Hash(){
// TODO Destructor
}
void Hash::setKey(char* tempKey){
this->key = tempKey;
}
void Hash::setNext(Hash* const tempNext){
this->next = tempNext;
}
char* Hash::getKey(){
return key;
}
Hash* Hash::getNext(){
return next;
}
In your code, you allocating only the getNext() nodes,
so you should delete only them, (you tried to delete &head[i] which wasn't allocated at all).
There is still an exception for double freeing some node, you should debug and follow the stack for figuring it out.
HashTable::~HashTable(){
for(int i = 0; i< TABLE_SIZE; i++){
Hash* node = head[i].getNext();
while(node != nullptr){
Hash* temp = nullptr;
if (node -> getNext()) {
temp = node->getNext();
}
delete node;
node= temp;
}
}
delete[] head;
}
Output:
----------------------------------------
INDEX: 0
Key: Art
----------------------------------------
----------------------------------------
INDEX: 1
Key: Engineering
----------------------------------------
----------------------------------------
INDEX: 2
Key: Miscellanous
----------------------------------------
----------------------------------------
INDEX: 3
Key: Software
----------------------------------------
----------------------------------------
INDEX: 4
Key: Programming
----------------------------------------
double free or corruption (fasttop)
Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

Class Linked List Template run time error

I have a linked list class that uses templates for both the Node class and the List class. I've done some debugging and come to the conclusion that in my Node class, the member functions cannot access the member data, but the constructors can. I would like to know how i can fix this!
#include <iostream>
#include <fstream>
#include <string>
#include "List.h"
using namespace std;
int main()
{
ifstream fileIn("data1.txt");
List<int> studentList;
if(fileIn.fail())
cout << "file did not open" << endl;
else
studentList.add(fileIn);
fileIn.close();
cin.get();
cin.ignore();
return 0;
}
//List.h
//ignore the commented methods, have yet to write them.
#ifndef LIST_H
#define LIST_H
#include <cstdlib>
#include <iostream>
#include <fstream>
#include "Node.h"
using namespace std;
template <class NumType>
class List
{
int counter;
bool isEmpty();
const bool print(){
}
public:
Node<NumType> * head;
List()
{
this->head = NULL;
counter = 0;
}
~List()
{
}
//place in an order thart keeps the array in ascending order
void add(ifstream &);
/*
Node* location(Node *){
}
bool remove(const int){
}
bool clear(){
}
const void peek(const Node*){
}
//average of all test scores or just one students test scores?
float average(){
}
char grade(){
}
*/
};
#include "List.cpp"
#endif
//List.cpp
#include "List.h"
using namespace std;
template <class NumType>
bool List<NumType> :: isEmpty()
{
cout << "inside isEmpty" << endl;
return(head == NULL);
}
template <class NumType>
void List<NumType> :: add(ifstream & fin)
{ int dummyID;
NumType tests[3];
string dummyName;
while(fin >> dummyID)
{ fin.ignore();
getline(fin, dummyName);
for(int x = 0; x < 3; x++)
fin >> tests[x];
fin.ignore();
cout << dummyID << endl;
cout <<dummyName << endl;
for(int y = 0; y < 3; y++)
cout << tests[y] << " ";
if(isEmpty())
{
this->head = new Node<NumType>(NULL, tests, dummyID, dummyName);
counter++;cout << "inside" << endl;
}
else
{
Node<NumType> *newNode = new Node<NumType>(NULL, tests, dummyID, dummyName);
Node<NumType> *first = new Node<NumType>(NULL, tests, dummyID, dummyName);
Node<NumType> *second;
first = this->head;
second = this->head->getNext();
//create location() method to handle this!
for(int x = 0; x < counter; x++)
{
if(first->getID() > newNode->getID())
{
head = newNode;
counter++;
break;
}
else if(first->getID() < newNode->getID() && second->getID() > newNode->getID())
{
newNode->setNext(second);
first->setNext(newNode);
counter++;
break;
}
else if(second->getID() < newNode->getID() && second->getNext() == NULL)
{
second->setNext(newNode);
counter++;
break;
}
else
{
first = second;
second = second->getNext();
}
}
}
}
Node<NumType> * temp = head;
for(int x = 0; x <= counter; x++)
{
NumType *arr;
cout << temp->getID() << endl << temp->getName() << endl;
arr = temp->getAllScores();
for(int y = 0; y <3 ; y++)
cout << *(arr+y) << endl;
temp = temp->getNext();
}
}
//Node.h
#ifndef NODE_H
#define NODE_H
#include <cstdlib>
#include <iostream>
using namespace std;
template <class ItemType>
class Node
{
static const int SIZE = 3;
int ID;
ItemType scores[SIZE];
string name;
Node *next;
public:
Node()
{
this->scores[0] = 0;
this->scores[1] = 0;
this->scores[2] = 0;
this->name = "";
this->ID = 0;
this->next = NULL;
}
Node(Node * nPtr, ItemType tests[], int num, string n)
{
this->next = nPtr;
for(int z = 0; z < SIZE; z++)
this->scores[z] = tests[z];
this->ID = num;
this->name = n;
}
~Node(){}
void setNext( Node * );
string getName();
int getID();
ItemType* getAllScores();
Node* getNext();
};
#include "Node.cpp"
#endif
Node.cpp
#include "Node.h"
#include <string>
using namespace std;
template <class ItemType>
void Node<ItemType> :: setNext( Node * nextPtr)
{
cout << "inside setNext()" << endl;
this->next = nextPtr;
cout << "exited setNext()" << endl;
}
template <class ItemType>
string Node<ItemType> :: getName()
{
return (this->name);
}
template <class ItemType>
int Node<ItemType> :: getID()
{
return (this->ID);
}
template <class ItemType>
ItemType* Node<ItemType> :: getAllScores()
{
return (this->scores);
}
template <class ItemType>
Node<ItemType> * Node<ItemType> :: getNext()
{
return (this->next);
}
I think I found the error. The first time you run the add method head is set, but the second time you are trying to set the second value. You have this code
first = this->head;// this is the first element
second = this->head->getNext(); // this is null (hast been assign yet
then you go inside of a for loop, and in the first "else if" statement you have this:
else if(first->getID() < newNode->getID() && second->getID() > newNode->getID())
when you say second->getID() you are saying null->getID() causing you a segmentation fault.
I hope this fixes your problem. Good luck!

new operator is not allocating memory properly.

my code is suppose to create a singly linked list using and array of nodes.
each Node has variable item which hold data and variable next which holds the index of the next node in the list. the last node has -1 in its next data field to simulate a nullptr. head holds the index of the first node in the list.
for some reason when i try to create new memory the program throws an instance of bad_alloc
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
#include "ArrayList.h"
#include <iostream>
using namespace std;
ArrayList::ArrayList(char ch){
array = new Node[Size];
(array[0]).item = ch;
(array[0]).next = 1;
free = 1;
head = 0;
}
bool ArrayList::cons(char ch) {
if (this->isFull()){
this->doubleArray();
}
(array[free]).item = ch;
(array[free]).next = head;
head = free;
free++;
// cout << free << endl;
return true;
}
bool ArrayList::isFull() const{
int current = head;
int count =0;
while( (array[current]).next != -1 ){
count++;
current = (array[current]).next;
}
return (count == Size) ? true : false;
}
bool ArrayList::doubleArray() {
int oldSize = Size;
Size *=2;
Node* newArray = new Node[Size]; // problem occurs here, i think
int count =0;
while(oldSize >= count ){
(newArray[count]).item = (array[count]).item;
(newArray[count]).next = (array[count]).next;
count++;
}
free = count +1;
delete [] array;
array = newArray;
cout <<"free: "<< free << endl;
return true; // come up with thiss
}
void ArrayList::print() const{
if (head == -1) return;
int current = head;
cout << "[ ";
while( (array[current]).next != -1){
cout << (array[current]).item <<" ";
current = (array[current]).next;
}
cout << (array[current]).item <<"]";
return;
}
///////////////////////////////////
#ifndef ARRAYLIST_H
#define ARRAYLIST_H
#include <iostream>
using namespace std;
class Node{
public:
char item;
int next;
Node(){
next = -1;
}
Node(char input){
this->item = input;
next = -1;
}
};
class ArrayList{
public:
ArrayList(char ch);
int length() const;
void print() const;
private:
bool doubleArray();
bool isFull() const;
Node* array;
int Size = 5;
int head = -1;
int free = 0;
};
#endif
////////////////////////////////////////
#include <iostream>
#include "ArrayList.h"
using namespace std;
int main(){
ArrayList list('1');
list.cons('2');
list.cons('3');
list.cons('4');
list.cons('5');
list.cons('6');
list.cons('7');
list.print();
//cout << list.length();
return 0;
}

Including .h File for 2 Classes

I want to turn this single .cpp file into multiple ones but I'm having trouble doing so. I'm getting undeclared identifier and 'children' : is not a member of 'Node' compiler errors.
Here is my original entire code:
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
Node();
~Node() {}
char content();
void setContent(char c);
bool wordMarker();
void setWordMarker();
Node* findChild(char c);
void appendChild(Node* child);
vector<Node*> children();
private:
char m_Content;
bool m_Marker;
vector<Node*> m_Children;
};
class Trie {
public:
Trie();
~Trie();
void addWord(string s);
bool searchWord(string s);
void deleteWord(string s);
private:
Node* root;
};
Node::Node()
{
m_Content = ' '; m_Marker = false;
}
char Node::content()
{
return m_Content;
}
void Node::setContent(char c)
{
m_Content = c;
}
bool Node::wordMarker()
{
return m_Marker;
}
void Node::setWordMarker()
{
m_Marker = true;
}
void Node::appendChild(Node* child)
{
m_Children.push_back(child);
}
vector<Node*> Node::children()
{
return m_Children;
}
Node* Node::findChild(char c)
{
for (int i = 0; i < m_Children.size(); i++)
{
Node* tmp = m_Children.at(i);
if (tmp->content() == c)
{
return tmp;
}
}
return NULL;
}
Trie::Trie()
{
root = new Node();
}
Trie::~Trie()
{
// Free memory
}
void Trie::addWord(string s)
{
Node* current = root;
if (s.length() == 0)
{
current->setWordMarker(); // an empty word
return;
}
for (int i = 0; i < s.length(); i++)
{
Node* child = current->findChild(s[i]);
if (child != NULL)
{
current = child;
}
else
{
Node* tmp = new Node();
tmp->setContent(s[i]);
current->appendChild(tmp);
current = tmp;
}
if (i == s.length() - 1)
current->setWordMarker();
}
}
bool Trie::searchWord(string s)
{
Node* current = root;
while (current != NULL)
{
for (int i = 0; i < s.length(); i++)
{
Node* tmp = current->findChild(s[i]);
if (tmp == NULL)
return false;
current = tmp;
}
if (current->wordMarker())
return true;
else
return false;
}
return false;
}
// Test program
int main()
{
Trie* trie = new Trie();
trie->addWord("Hello");
trie->addWord("Balloon");
trie->addWord("Ball");
if (trie->searchWord("Hell"))
cout << "Found Hell" << endl;
if (trie->searchWord("Hello"))
cout << "Found Hello" << endl;
if (trie->searchWord("Helloo"))
cout << "Found Helloo" << endl;
if (trie->searchWord("Ball"))
cout << "Found Ball" << endl;
if (trie->searchWord("Balloon"))
cout << "Found Balloon" << endl;
delete trie;
}
My attempt:
node.h
#ifndef NODE_INCLUDED
#define NODE_INCLUDED
class Node {
public:
Node();
~Node() {}
char content();
void setContent(char c);
bool wordMarker();
void setWordMarker();
Node* findChild(char c);
void appendChild(Node* child);
vector<Node*> children();
private:
char m_Content;
bool m_Marker;
vector<Node*> m_Children;
};
#endif // NODE_INCLUDED
trie.h
#ifndef TRIE_INCLUDED
#define TRIE_INCLUDED
class Trie {
public:
Trie();
~Trie();
void addWord(string s);
bool searchWord(string s);
void deleteWord(string s);
private:
Node* root;
};
#endif //TRIE_INCLUDED
node.cpp
#include "node.h"
#include <iostream>
#include <vector>
using namespace std;
Node::Node()
{
m_Content = ' '; m_Marker = false;
}
char Node::content()
{
return m_Content;
}
void Node::setContent(char c)
{
m_Content = c;
}
bool Node::wordMarker()
{
return m_Marker;
}
void Node::setWordMarker()
{
m_Marker = true;
}
void Node::appendChild(Node* child)
{
m_Children.push_back(child);
}
vector<Node*> Node::children()
{
return m_Children;
}
Node* Node::findChild(char c)
{
for (int i = 0; i < m_Children.size(); i++)
{
Node* tmp = m_Children.at(i);
if (tmp->content() == c)
{
return tmp;
}
}
return NULL;
}
trie.cpp
Trie::Trie()
{
root = new Node();
}
Trie::~Trie()
{
// Free memory
}
void Trie::addWord(string s)
{
Node* current = root;
if (s.length() == 0)
{
current->setWordMarker(); // an empty word
return;
}
for (int i = 0; i < s.length(); i++)
{
Node* child = current->findChild(s[i]);
if (child != NULL)
{
current = child;
}
else
{
Node* tmp = new Node();
tmp->setContent(s[i]);
current->appendChild(tmp);
current = tmp;
}
if (i == s.length() - 1)
current->setWordMarker();
}
}
bool Trie::searchWord(string s)
{
Node* current = root;
while (current != NULL)
{
for (int i = 0; i < s.length(); i++)
{
Node* tmp = current->findChild(s[i]);
if (tmp == NULL)
return false;
current = tmp;
}
if (current->wordMarker())
return true;
else
return false;
}
return false;
}
main.cpp
#include "node.h"
#include <iostream>
#include <vector>
using namespace std;
// Test program
#include "node.h" //is this needed?
#include "trie.h" //is this needed?
int main()
{
Trie* trie = new Trie();
trie->addWord("Hello");
trie->addWord("Balloon");
trie->addWord("Ball");
if (trie->searchWord("Hell"))
cout << "Found Hell" << endl;
if (trie->searchWord("Hello"))
cout << "Found Hello" << endl;
if (trie->searchWord("Helloo"))
cout << "Found Helloo" << endl;
if (trie->searchWord("Ball"))
cout << "Found Ball" << endl;
if (trie->searchWord("Balloon"))
cout << "Found Balloon" << endl;
delete trie;
}
So here is what I got working, I comment on things I have added or removed.
node.h
#ifndef NODE_INCLUDED
#define NODE_INCLUDED
#include <vector> //Class Node uses vector so it should be included
#include <iostream> //Class Node uses iostream so it should be included
class Node {
public:
Node();
~Node() {}
char content();
void setContent(char c);
bool wordMarker();
void setWordMarker();
Node* findChild(char c);
void appendChild(Node* child);
std::vector<Node*> children();
private:
char m_Content;
bool m_Marker;
std::vector<Node*> m_Children;
};
#endif // NODE_INCLUDED
trie.h
#ifndef TRIE_INCLUDED
#define TRIE_INCLUDED
#include "node.h" //Class Trie uses Node so it should include it
#include <string> //Class Node uses string so it should include it
class Trie {
public:
Trie();
~Trie();
void addWord(string s);
bool searchWord(string s);
void deleteWord(string s);
private:
Node* root;
};
#endif //TRIE_INCLUDED
node.cpp
#include "node.h"
//#include <iostream>
//#include <vector>
using namespace std;
//Here you got all includes right but they should be in the header file!
Node::Node()
{
m_Content = ' '; m_Marker = false;
}
char Node::content()
{
return m_Content;
}
void Node::setContent(char c)
{
m_Content = c;
}
bool Node::wordMarker()
{
return m_Marker;
}
void Node::setWordMarker()
{
m_Marker = true;
}
void Node::appendChild(Node* child)
{
m_Children.push_back(child);
}
vector<Node*> Node::children()
{
return m_Children;
}
Node* Node::findChild(char c)
{
for (int i = 0; i < m_Children.size(); i++)
{
Node* tmp = m_Children.at(i);
if (tmp->content() == c)
{
return tmp;
}
}
return NULL;
}
trie.cpp
#include "trie.h" //Trie.cpp should at least contain its header file
Trie::Trie()
{
root = new Node();
}
Trie::~Trie()
{
// Free memory
}
void Trie::addWord(string s)
{
Node* current = root;
if (s.length() == 0)
{
current->setWordMarker(); // an empty word
return;
}
for (int i = 0; i < s.length(); i++)
{
Node* child = current->findChild(s[i]);
if (child != NULL)
{
current = child;
}
else
{
Node* tmp = new Node();
tmp->setContent(s[i]);
current->appendChild(tmp);
current = tmp;
}
if (i == s.length() - 1)
current->setWordMarker();
}
}
bool Trie::searchWord(string s)
{
Node* current = root;
while (current != NULL)
{
for (int i = 0; i < s.length(); i++)
{
Node* tmp = current->findChild(s[i]);
if (tmp == NULL)
return false;
current = tmp;
}
if (current->wordMarker())
return true;
else
return false;
}
return false;
}
main.cpp
//#include "node.h" //You don't use Node here, so don't include it!
//Keep your code simple
#include <iostream>
#include <vector>
using namespace std;
// Test program
//#include "node.h" //is this needed? Not needed because you don't use
//its declarations directly here and
//you had it declared before
#include "trie.h" //is this needed? Yes, it is. You use that class
//directly here, so it should include it
int main()
{
Trie* trie = new Trie();
trie->addWord("Hello");
trie->addWord("Balloon");
trie->addWord("Ball");
if (trie->searchWord("Hell"))
cout << "Found Hell" << endl;
if (trie->searchWord("Hello"))
cout << "Found Hello" << endl;
if (trie->searchWord("Helloo"))
cout << "Found Helloo" << endl;
if (trie->searchWord("Ball"))
cout << "Found Ball" << endl;
if (trie->searchWord("Balloon"))
cout << "Found Balloon" << endl;
delete trie;
}
By the way, you should not use using namespace in header files as it is a bad practice

Priority Queue that utilizes BST -- DeleteLargest doesn't work

I am creating a priority queue that utilizes a binary search tree for my Data Structures class. But when I attempt to output the queue I always get 0. I have looked over my DeleteLargest and Dequeue member function but I can't find the mistake
Test.cpp
#include <iostream>
#include "CTree.h"
#include "PriorityQueueBST.h"
using namespace std;
int main()
{
int num, input, output;
cout << "Enter number of elements: ";
cin >> num;
PriorityQueueBST p;
for (int x = 0; x < num; x++)
{
cout << "Enter number " << x + 1
<< " of " << num << ": ";
cin >> input;
p.Enqueue(input);
}
for (int y = 0; y < num; y++)
{
cout << "Outputting number " << y + 1
<< " of " << num << ": ";
if(p.IsEmpty())
{
break; //we are done (this is an error!)
}
output = p.Dequeue();
cout << output << endl;
}
system("pause");
return 0;
//CTree* tr = new CTree();
//
//for (int i = 0; i < 3; i++)
// tr->Add();
//tr->View();
//system("pause");
//return 0;
}
BST Declaration file
//#ifndef CTREE_H
//#define CTREE_H
//using namespace std;
struct TreeNode
{
int info;
TreeNode* leftLink;
TreeNode* rightLink;
};
class CTree
{
private:
void AddItem( TreeNode*&, TreeNode*);
void DisplayTree(TreeNode*);
void Retrieve(TreeNode*&, TreeNode*,bool&);
void Destroy(TreeNode*&);
public:
CTree();
~CTree();
void Add();
void View();
bool IsEmpty();
int DeleteLargest(TreeNode*&);
TreeNode *tree;
};
//#endif
BST Implementation file
#include <iostream>
#include <string>
using namespace std;
#include "CTree.h"
CTree::CTree()
{
tree = NULL;
}
CTree::~CTree()
{
Destroy(tree);
}
void CTree::Destroy(TreeNode*& tree)
{
if (tree != NULL)
{
Destroy(tree->leftLink);
Destroy(tree->rightLink);
delete tree;
}
}
bool CTree::IsEmpty()
{
if(tree == NULL)
{
return true;
}
else
{
return false;
}
}
void CTree::Add()
{
TreeNode* newPerson = new TreeNode();
/*cout << "Enter the person's name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin.getline(newPerson->name, 20);*/
/* cout << "Enter the person's contribution: ";
cin >> newPerson->info;*/
/*bool found = false;*/
newPerson->leftLink = NULL;
newPerson->rightLink = NULL;
/*Retrieve(tree, newPerson, found);
if (found)
cout << "info allready entered\n";
else*/
AddItem(tree, newPerson);
}
void CTree::View()
{
if (IsEmpty())
{
cout<<"The list is empy";
}
else
{
DisplayTree(tree);
}
};
void CTree::AddItem( TreeNode*& ptr, TreeNode* newPer )
{
if (ptr == NULL)
{
ptr = newPer;
}
else if ( newPer->info < ptr->info)
AddItem(ptr->leftLink, newPer);
else
AddItem(ptr->rightLink, newPer);
}
void CTree::DisplayTree(TreeNode* ptr)
{
if (ptr == NULL)
return;
DisplayTree(ptr->rightLink);
cout << ptr->info << endl; //cout<<ptr->name<<" "<<"$"<<ptr->info <<endl;
DisplayTree(ptr->leftLink);
}
void CTree::Retrieve(TreeNode*& ptr, TreeNode* newPer, bool& found)
{
{
if (ptr == NULL)
{
found = false; // item is not found.
}
else if ( newPer->info < ptr->info)
{
Retrieve(ptr->leftLink, newPer, found);
}
// Search left subtree.
else if (newPer->info > ptr->info)
{
Retrieve(ptr->rightLink, newPer, found);// Search right subtree.
}
else
{
//newPer.info = ptr->info; // item is found.
found = true;
}
}
}
int CTree::DeleteLargest(TreeNode*& tr)
{
int largest = 0;;
TreeNode* prev;
TreeNode* cur;
prev = NULL;
cur = tr;
if (tr == NULL)
{
cout << "The tree is empty"<<endl;
}
else if (tr->rightLink == NULL)
{
largest = tr->info;
}
else
{
prev = tr;
tr = tr->rightLink;
DeleteLargest(tr);
}
return largest;
}
Priority Queue Declaration
//#include <iostream>
//using namespace std;
//#include "SortedLinkedList.h"
#ifndef PRIORITYQUEUESLL__H
#define PRIORITYQUEUESLL__H
class PriorityQueueBST
{
public:
PriorityQueueBST();
~PriorityQueueBST();
void Enqueue(int);
int Dequeue();
bool IsEmpty();
private:
CTree* ourTree;
//sslNode* head;
};
#endif
Priority Queue Implementation
#include <iostream>
using namespace std;
#include "CTree.h"
#include "PriorityQueueBST.h"
PriorityQueueBST::PriorityQueueBST()
{
ourTree = new CTree();
//head = NULL;
}
PriorityQueueBST::~PriorityQueueBST()
{
}
void PriorityQueueBST::Enqueue(int dataToEnter)
{
ourTree->Add();
}
int PriorityQueueBST::Dequeue()
{
//check for empty??
return ourTree->DeleteLargest(ourTree->tree);
}
bool PriorityQueueBST::IsEmpty()
{
return ourTree->IsEmpty();
}
Your output is always 0 because in
int CTree::DeleteLargest(TreeNode*& tr)
{
int largest = 0;;
TreeNode* prev;
TreeNode* cur;
prev = NULL;
cur = tr;
if (tr == NULL)
{
cout << "The tree is empty"<<endl;
}
else if (tr->rightLink == NULL)
{
largest = tr->info;
}
else
{
prev = tr;
tr = tr->rightLink;
DeleteLargest(tr);
}
return largest;
}
you only set largest to something potentially != 0 if tr->rightlink is NULL. Otherwise you recur and set the largest variable local to another invocation of the function. That change is lost when the recursion goes up again, and in the topmost invocation, largest is still 0.
In the last line of the else branch, you should either
largest = DeleteLargest(tr);
or
return DeleteLargest(tr);
Another problem is that, despite its name, deleteLargest doesn't actually delete anything, so with the above, you would still always get the same value.