C++ Hash Table using chaining, remove method - c++

I'm implementing a Hash Table in C++ using chaining. The code builds with no errors and the table constucts fine using the insert method. However, when I call the remove method I receive the following error:
Unhandled exception at 0x00c53be9 in HashTable.exe: 0xC0000005: Access violation reading location 0x00000000.
Hash Entry Code:
#include <string>
#include <vector>
template <class T>
class HashEntry
{
private:
int key; //lookup key
T value; //hash data
HashEntry<T> *next;
public:
HashEntry(int key, T value);
HashEntry();
int& getKey();
T& getValue();
void setValue(T value);
HashEntry<T>* getNext();
void setNext(HashEntry *next);
bool operator == (HashEntry& rhs);
bool operator != (HashEntry& rhs);
HashEntry<T>& operator = (HashEntry& rhs);
};
template <class T>
HashEntry<T>::HashEntry(int key, T value)
{
this->key = key;
this->value = value;
this->next= nullptr;
}
template <class T>
HashEntry<T>::HashEntry()
{
this->key = 0;
this->next= nullptr;
}
template <class T>
int& HashEntry<T>::getKey()
{
return key;
}
template <class T>
T& HashEntry<T>::getValue()
{
return value;
}
template <class T>
void HashEntry<T>::setValue(T value)
{
this->value = value;
}
template <class T>
HashEntry<T>* HashEntry<T>::getNext()
{
return next;
}
template <class T>
void HashEntry<T>::setNext (HashEntry *next)
{
this->next = next;
}
template <class T>
bool HashEntry<T>::operator == (HashEntry& rhs)
{
return ((this->getKey() == rhs.getKey()) && (this->getValue() == rhs.getValue()));
}
template <class T>
bool HashEntry<T>::operator != (HashEntry& rhs)
{
return ((this->getKey() != rhs.getKey()) && (this->getValue() != rhs.getValue()));
}
template <class T>
HashEntry<T>& HashEntry<T>::operator = (HashEntry& rhs)
{
this->key = rhs.getKey();
this->value = rhs.getValue();
this->next = rhs.getNext();
return *this;
}
Hash Table code:
template <class T>
class HashTable
{
private:
std::vector<HashEntry<T>> table;
static const int DEFAULT_TABLE_SIZE = 128;
int TABLE_SIZE;
public:
HashTable();
void insert(int key, T value);
void remove(int key);
void get(int key);
~HashTable();
};
template <class T>
HashTable<T>::HashTable()
{
TABLE_SIZE = DEFAULT_TABLE_SIZE;
table.resize(TABLE_SIZE);
}
Remove Method Code:
template <class T>
void HashTable<T>::remove(int key)
{
int hashFunc = (key % TABLE_SIZE);
if (table[hashFunc] != HashEntry<T>())
{
HashEntry<T> prevEntry = HashEntry<T>();
HashEntry<T> entry = table[hashFunc];
while (entry.getNext() != nullptr && entry.getKey() != key)
{
prevEntry = entry;
entry = *entry.getNext();
}
if (entry.getKey() == key)
{
if (prevEntry == HashEntry<T>())
{
HashEntry<T> nextEntry = *entry.getNext(); //Where the exception is thrown
entry = HashEntry<T>();
table[hashFunc] = nextEntry;
}
else
{
HashEntry<T> *next = entry.getNext();
entry = HashEntry<T>();
prevEntry.setNext(next);
}
}
}
}

while (entry.getNext() != nullptr && entry.getKey() != key)
{
prevEntry = entry;
entry = *entry.getNext();
}
Few lines later, using entry generated above:
HashEntry<T> nextEntry = *entry.getNext(); //Where the exception is thrown
The while "makes" entry.getNext() a nullptr. And, later, you are trying to dereference it. And dereferencing nullptr... is a Bad Thing (tm).
Btw., why aren't you operating on pointers? I may be wrong, but looking at your code, I have a feeling that you want to modify original objects... and local objects looks like copies.

Related

Empty Dynamic List

I've created a simple dynamic template list and i'm having some issue clearing the entire list.
List.h
#ifndef LIST_H
#define LIST_H
#include <Node.h>
template <class T> class List
{
public:
typedef Node<T> node_type;
typedef node_type* node_pointer;
typedef T data_type;
typedef T& reference_type;
List();
void push_back(data_type);
reference_type at(int);
void clear();
void swap(int,int);
int size();
private:
int list_size = 0;
node_pointer head, tail;
};
template <class T> List<T>::List()
{
head=NULL;
tail=NULL;
}
template <class T> void List<T>::push_back(data_type data)
{
if(head == NULL) {
head = new node_type(data);
tail = head;
} else {
node_pointer temp = new node_type(data);
temp->setNextNull();
tail->setNext(temp);
tail = tail->getNext();
}
list_size++;
}
template <class T> typename List<T>::reference_type List<T>::at(int x)
{
node_pointer pointer=head;
for(int i=0; i<x; i++)
pointer=pointer->getNext();
return pointer->getData();
}
template <class T> void List<T>::clear()
{
node_pointer pointer = head;
for(int i=0; i<list_size; i++) {
node_pointer temp = pointer;
pointer=pointer->getNext();
delete(temp);
}
head=NULL;
list_size=0;
}
template <class T> void List<T>::swap(int x, int y)
{
data_type buffer=at(x);
at(x)=at(y);
at(y)=buffer;
}
template <class T> int List<T>::size()
{
return list_size;
}
#endif // LIST_H
Node.h
template <class T> class Node
{
public:
typedef T data_type;
typedef T& reference_type;
Node(data_type _data);
void setData(data_type);
void setNextNull();
void setNext(Node*);
reference_type getData();
Node* getNext();
private:
data_type data;
Node* next;
};
template <class T> Node<T>::Node(data_type _data) : data(_data)
{
setNextNull();
}
template <class T> void Node<T>::setData(data_type _data)
{
data=_data;
}
template <class T> void Node<T>::setNextNull()
{
next=NULL;
}
template <class T> void Node<T>::setNext(Node* _next)
{
next=_next;
}
template <class T> typename Node<T>::reference_type Node<T>::getData()
{
return data;
}
template <class T> typename Node<T>::Node* Node<T>::getNext()
{
return next;
}
If I clear the list calling the "clear" method I get all sorts of errors in almost every other method, but if I use the version below the list works perfectly.
template <class T> void List<T>::clear()
{
head=NULL;
tail=NULL;
list_size=0;
}
The problem only appears if I use the delete function to clear memory. How can I solve this issue?
Your code is very dangerious, because you skipped important checks. Try to use following implementation of at():
template <class T> typename List<T>::reference_type List<T>::at(int x)
{
if (x < 0 || x >= list_size || list_size <= 0)
return DATA_WITH_ERROR_FLAG; // since you return data instead of pointer,
// you can't return NULL here
// (you need special constant for error status
// or support it another way)
node_pointer pointer=head;
for(int i=0; i<x; i++)
{
if (!pointer)
return DATA_WITH_ERROR_FLAG;
pointer=pointer->getNext();
}
if (!pointer)
return DATA_WITH_ERROR_FLAG;
return pointer->getData();
}
After it you have to add checks after each at() call. For example, you have to modify swap() to make it safe too:
template <class T> void List<T>::swap(int x, int y)
{
data_type v1=at(x);
data_type v2=at(y);
if (v1 == DATA_WITH_ERROR_FLAG || v2 == DATA_WITH_ERROR_FLAG)
return; // and somehow set error flag!
data_type t=v1;
v1 = v2;
v2 = t;
}
I.e. you need to check correctness everywhere if you don't like such problems. And it is necessary to support returninig of error status to simplify analysis of errors.
Change your clear() method to this:
template <class T> void List<T>::clear()
{
node_pointer pointer = head;
while (pointer != NULL) {
node_pointer temp = pointer-getNext();
delete pointer;
pointer = temp;
}
head=NULL;
tail=NULL;
list_size=0;
}
You have a memory leak in your code. You don't delete all the list by simply pointing head and tail to NULL.
The best way to do this is to create a delete() function then loop through the whole list while it is not empty and delete node by node.
void deleteHead()
{
if(head != NULL)
{
node *temp = head;
head = head->next;
delete temp;
size--;
}
}
bool isEmpty()
{
return head==NULL;
//return size == 0; <-- this is ok as well.
}
void clear()
{
while(! isEmpty())
{
deleteHead();
}
tail = head; //head = NULL
}

Stack implementation C++

I have implemented a stack using the next class:
template <typename T, int lungime> class Depou
{
private:
T *depouarray;
int top;
public:
Depou ()
{
this -> top = -1;
depouarray = (T *) calloc (lungime, sizeof (T));
}
~Depou ()
{
free (depouarray);
}
void push (T x)
{
if (top >= lungime - 1)
{
return;
}
top ++;
depouarray [top] = x;
}
T pop ()
{
if (isEmpty ())
{
return -1;
}
T x;
x = depouarray [top];
top --;
return x;
}
T peek ()
{
if (isEmpty ())
{
return -1;
}
return depouarray[top];
}
int isEmpty ()
{
return (top < 0);
}
}
My problem is the next one:
After I've added an element to the stack, let's say 3, I verified it and it showed 3.
Next, I added another element, let's say 4, I verified the content of the stack and it showed a very high number (which is surely junk) and 4. I cannot understand why it transforms the first elements into junk, leaving only the last element added as it should be.
As my colleague pointed out, you have many errors within your code and I think i t would be too much effort to correct it. Hence I'm giving you a stack implementation.
A stack is a FILO structure. The best way to implement it is to use Node and to link them together. Look at the code below, it is straight forward. Let me know if you have questions.
template <class T>
class Stack {
public:
Stack();
~Stack();
void push(const T&);
void pop(T& out);
T pop();
bool is_empty() const;
void clear();
private:
class Node {
public:
Node(const T& t, Node* c);
T contain;
Node* next;
};
Node* peak;
};
template <class T>
Stack<T>::Stack()
{
peak = NULL;
}
template <class T>
Stack<T>::~Stack()
{
clear();
}
template <class T>
bool Stack<T>::is_empty() const
{
return peak == NULL;
}
template <class T>
void Stack<T>::clear()
{
while(!is_empty())
pop();
}
template <class T>
Stack<T>::Node::Node(const T& t, Node* c) : next(c)
{
contain = t;
}
template <class T>
void Stack<T>::push(const T& t)
{
peak = new Node(t, peak);
assert(peak);
}
template <class T>
T Stack<T>::pop()
{
assert(peak);
Node c(*peak);
delete peak;
peak = c.next;
return c.contain;
}
template <class T>
void Stack<T>::pop(T& t)
{
assert(peak != NULL);
t = peak->contain;
Node* c = peak;
peak = peak->next;
delete c;
}

c++ redefine operator<() and operator!=()

I have this implementation of queue:
#include<iostream>
using namespace std;
template <typename T>
struct elem_q
{
T inf;
elem_q<T>* link;
};
template <typename T = int>
class Queue
{
public:
Queue();
~Queue();
Queue(const Queue&);
Queue& operator= (const Queue&);
bool empty()const;
void push(const T&);
void pop(T&);
void head(T&) const;
void print();
int length();
private:
elem_q<T> *front;
elem_q<T> *rear;
void copyQueue(const Queue<T>);
void deleteQueue();
};
template <typename T>
Queue<T>::Queue()
{
front = rear = NULL;
}
template <typename T>
Queue<T>::~Queue()
{
deleteQueue();
}
template <typename T>
Queue<T>::Queue(const Queue<T>& r)
{
copyQueue(r);
}
template <typename T>
Queue<T>& Queue<T>::operator=(const Queue<T>& r)
{
if(this != &r)
{
deleteQueue();
copyQueue(r);
}
return *this;
}
template <typename T>
void Queue<T>::copyQueue(const Queue<T> r)
{
front = rear = NULL;
elem_q<T> *p = r.front;
while(p)
{
push(p->inf);
p = p->link;
}
}
template <typename T>
void Queue<T>::deleteQueue()
{
T x;
while (!empty())
{
pop(x);
}
}
template <typename T>
bool Queue<T>::empty() const
{
return rear == NULL;
}
template <typename T>
void Queue<T>::push(const T& x)
{
elem_q<T> *p = new elem_q<T>;
p->inf = x;
p->link = NULL;
if (rear) rear->link = p;
else front = p;
rear = p;
}
template <typename T>
void Queue<T>::pop(T& x)
{
if(empty())
{
cout<<"The queue is empty.\n";
}
else
{
elem_q<T> *q = front;
x = q->inf;
if (q == rear)
{
rear = NULL;
front = NULL;
}
else front = q->link;
delete q;
}
}
template <typename T>
void Queue<T>::head(T& x) const
{
if(empty())
{
cout<<"The queue is empty.\n";
}
else
{
x = front->inf;
}
}
template <typename T>
void Queue<T>::print()
{
T x;
while(!empty())
{
pop(x);
cout<<x<<" ";
}
cout<<endl;
}
template <typename T>
int Queue<T>::length()
{
T x;
int n = 0;
while(!empty())
{
pop(x);
n++;
}
return n;
}
template<typename T>
void minqueue(Queue<T> q,T& min,Queue<T>& newq)
{
T x;
q.pop(min);
while (!q.empty())
{
q.pop(x);
if (x < min)
{
newq.push(min);
min = x;
}
else newq.push(x);
}
}
template<typename T>
void sortQueue(Queue<T> q,Queue<T>& newq)
{
while(!q.empty())
{
T min;
Queue<T> q1;
minqueue(q , min ,q1);
newq.push(min);
q = q1;
}
}
template<typename T>
Queue<T> merge(Queue<T> p,Queue<T> q,const T& dummy)
{
p.push(dummy);
q.push(dummy);
Queue<T> r;
T x,y;
p.pop(x);
q.pop(y);
while (!p.empty() && !q.empty())
if (x < y)
{
r.push(x);
p.pop(x);
}
else
{
r.push(y);
q.pop(y);
}
if (!p.empty())
do
{
r.push(x);
p.pop(x);
}while (x != dummy);
else
do
{
r.push(y);
q.pop(y);
}while (y != dummy);
return r;
}
How can i redefine operator < and != because without them function minqueue,Sortqueue and merge do not work?Please help me...............................................
template <typename T>
struct elem_q
{
T inf;
elem_q<T>* link;
};
template <typename T>
bool operator <( const elem_q<T> &lhs, const elem_q<T> &rhs )
{
return ( lhs.inf < rhs.inf );
}
template <typename T>
bool operator ==( const elem_q<T> &lhs, const elem_q<T> &rhs )
{
return ( lhs.inf == rhs.inf );
}
template <typename T>
bool operator !=( const elem_q<T> &lhs, const elem_q<T> &rhs )
{
return ( !( lhs.inf == rhs.inf ) );
}
See how you already did this:
template <typename T>
Queue<T>& Queue<T>::operator=(const Queue<T>& r)
{
if(this != &r)
{
deleteQueue();
copyQueue(r);
}
return *this;
}
Overload the other operators you need, too.
Well, logical operators have rather expected syntax, looking like this:
bool ClassName::operator!=(const ClassName& other) const {
return //compare as apropriate.
}
However, I have to note two things:
First, you really need to go through the class design again -> there are wild inconsistencies in use of references, weird API and I am not even sure what exactly is minqueue is supposed to do, or rather why it does what it does.
Second, if you want to have queue that sorts itself, goes from minimal element and such, you should look up priority queue, or heap.

Binary Heap No Matching Function Error

I am working on a linked list type implementation of a binary heap, and as it is written I am getting some errors. Right now my main.cpp is a simple test for adding an element to the heap, but when I call my "add to heap" function it says it can't find it. Here is the code:
main.cpp
#include <QtCore/QCoreApplication>
#include "Queue.h"
#include "Heap.h"
#include <bitset>
#include <cmath>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Heap<int> H;
H.AddToHeap(1);
return a.exec();
}
Heap.h
#ifndef HEAP_H
#define HEAP_H
#include "Node.h"
#include <iostream>
#include <bitset>
#include <cmath>
enum BOUNDARY_ERRORS{OUT_OF_BOUNDS, INVALID_NODE};
template <typename T>
class Heap
{
public:
Heap();
Heap(const Heap &other);
void operator=(const Heap &other);
~Heap();
void AddToHeap(T &data);
Heap& operator<<(T &data);
T& Pop();
Heap& operator>>(T &destination);
bool Empty() { return size==0; }
T Peek();
template <typename U> friend
ostream& operator<<(const ostream &out, const Heap<U> &H);
template <typename U> friend
istream& operator>>(const istream &in, const Heap<U> &H);
private:
int size;
Node<T> *rootptr;
void AddToVacantNode(T &data);
Node<T>* FindNode(int n);
Node<T>* FindParentNode(int n);
Node<T>* LargestChild(Node<T> *nodeptr);
Node<T>* SmallestChild(Node<T> *nodeptr);
void Upheap();
void Downheap();
void Switch(Node<T> *a, Node<T> *b);
void Replace(Node<T> *a, Node<T> *b);
void Copy(const Heap &other);
bool MIN;
void Clear();
};
template <typename T>
Heap<T>::Heap()
{
size = 0;
rootptr = NULL;
MIN = 0;
}
template <typename T>
Heap<T>::Heap(const Heap<T> &other)
: Heap()
{
Copy(other);
}
template <typename T>
void Heap<T>::operator=(const Heap<T> &other)
{
Copy(other);
}
template <typename T>
Heap<T>::~Heap()
{
Clear();
}
template <typename T>
void Heap<T>::AddToVacantNode(T &data)
{
if (Empty())
rootptr = new Node<T>(data);
else
{
int destination = size + 1;
Node<T> newnode(data);
Node<T> *parentptr = FindParentNode(destination);
if (!destination%2)
parentptr->AddLeftChild(newnode);
else
parentptr->AddRightChild(newnode);
}
}
template <typename T>
Node<T>* Heap<T>::FindParentNode(int n)
{
if (n == 1)
return NULL;
int parentnumber;
if (!n%2)
{
parentnumber = n / 2;
Node<T> *nodeptr = FindNode(parentnumber);
return nodeptr;
}
else
{
parentnumber = (n - 1) / 2;
Node<T> *nodeptr = FindNode(parentnumber);
return nodeptr;
}
}
template <typename T>
void Heap<T>::Upheap()
{
Node<T> *parentptr = FindParentNode(size);
Node<T> *childptr = FindNode(size);
if (MIN)
{
while (parentptr && *childptr < *parentptr)
{
switch(parentptr, childptr);
parentptr = FindParentNode(parentptr);
childptr = FindParentNode(childptr);
}
return;
}
else
{
while (parentptr && *childptr > *parentptr)
{
switch(parentptr, childptr);
parentptr = FindParentNode(parentptr);
childptr = FindParentNode(childptr);
}
return;
}
}
template <typename T>
Node<T>* Heap<T>::LargestChild(Node<T> *nodeptr)
{
if (!nodeptr->LeftChild() && !nodeptr->RightChild())
return NULL;
else if (nodeptr->LeftChild() && !nodeptr->RightChild())
return nodeptr->LeftChild();
else if (nodeptr->RightChild() && !nodeptr->LeftChild())
return nodeptr->RightChild();
else
return (*(nodeptr->LeftChild() > *(nodeptr->RightChild())))?
nodeptr->LeftChild() : nodeptr->RightChild();
}
template <typename T>
Node<T>* Heap<T>::SmallestChild(Node<T> *nodeptr)
{
if (!nodeptr->LeftChild() && !nodeptr->RightChild())
return NULL;
else if (nodeptr->LeftChild() && !nodeptr->RightChild())
return nodeptr->LeftChild();
else if (nodeptr->RightChild() && !nodeptr->LeftChild())
return nodeptr->RightChild();
else
return (*(nodeptr->LeftChild() < *(nodeptr->RightChild())))?
nodeptr->LeftChild() : nodeptr->RightChild();
}
template <typename T>
void Heap<T>::Downheap()
{
Node<T> *nodeptr = FindNode(size);
*rootptr = *nodeptr;
}
template <typename T>
void Heap<T>::Replace(Node<T> *a, Node<T> *b)
{
a->Data() = b->Data();
b->NullPtrs();
Node<T> *parentptr = FindParentNode(b);
if (parentptr->LeftChild() = b)
{
parentptr->NullLeftChild();
delete b;
b = NULL;
}
else
{
parentptr->NullRightChild();
delete b;
b = NULL;
}
return;
}
template <typename T>
void Heap<T>::AddToHeap(T &data)
{
AddToVacantNode(data);
Upheap();
size++;
}
template <typename T>
Heap<T>& Heap<T>::operator<<(T &data)
{
AddToHeap(data);
return *this;
}
template <typename T>
T& Heap<T>::Pop()
{
return rootptr->Data();
Downheap();
size--;
}
template <typename T>
Heap<T>& Heap<T>::operator>>(T &destination)
{
destination = rootptr->Data();
Downheap();
size--;
}
template <typename T>
T Heap<T>::Peek()
{
if (!Empty())
return rootptr->Data();
}
template <typename T>
ostream& operator<<(const ostream &out, const Heap<T> &H)
{
return;
}
template <typename T>
istream& operator>>(const istream &in, const Heap<T> &H)
{
return;
}
template <typename T>
void Heap<T>::Switch(Node<T> *a, Node<T> *b)
{
T temp;
temp = a->Data();
a->SetData(b->Data());
b->SetData(temp);
}
template <typename T>
void Heap<T>::Copy(const Heap &other)
{
if (this != &other && !other.Empty())
{
MIN = other.MIN;
Node<T> *nodeptr;
Clear();
for (int n=1; n<=other.size; n++)
{
nodeptr = other.FindNode(n);
AddToHeap(nodeptr->data);
}
}
}
template <typename T>
Node<T>* Heap<T>::FindNode(int n)
{
if (n > size || n < 1)
throw OUT_OF_BOUNDS;
int x = floor(log(n)/log(2)+1);
bitset<20> bs(n);
Node<T> *nodeptr = rootptr;
for (int i=x-2; i>=0; i--)
{
if (!bs[i])
nodeptr = nodeptr->LeftChild();
else
nodeptr = nodeptr->RightChild();
}
return nodeptr;
}
template <typename T>
void Heap<T>::Clear()
{
for (int n=size; n>0; n++)
{
Node<T> *nodeptr = FindNode(n);
nodeptr->NullPtrs();
delete nodeptr;
}
rootptr->NullPtrs();
delete rootptr;
}
#endif // HEAP_H
Node.h
#ifndef NODE_H
#define NODE_H
#include <iostream>
template <typename T>
class Node
{
public:
Node();
Node(T &DATA);
Node(const Node<T> &other);
Node<T>& operator=(const Node<T> &other);
Node<T>& operator<<(const T &nodedata);
bool operator==(const Node<T> &other);
bool operator<(const Node<T> &other);
bool operator>(const Node<T> &other);
bool operator<=(const Node<T> &other);
bool operator>=(const Node<T> &other);
bool operator!=(const Node<T> &other);
~Node();
T Data() const { return data; }
void SetData(const T &nodedata);
void AddLeftChild(const Node<T> *leftchildptr);
void AddRightChild(const Node<T> *rightchildptr);
Node<T> *LeftChild() { return leftchild; }
Node<T> *RightChild() { return rightchild; }
void NullLeftChild() { leftchild = NULL; }
void NullRightChild() { rightchild = NULL; }
void NullPtrs() { leftchild = rightchild = NULL; }
template <typename U> friend
ostream& operator<<(ostream &out, Node<U> &node);
private:
T data;
Node<T> *leftchild;
Node<T> *rightchild;
void Copy(const Node<T> &other);
};
template <typename T>
Node<T>::Node()
{
NullPtrs();
return;
}
template <typename T>
Node<T>::Node(T &DATA)
{
NullPtrs();
data = DATA;
return;
}
template <typename T>
Node<T>::Node(const Node<T> &other)
{
Copy(other);
return;
}
template <typename T>
Node<T>& Node<T>::operator=(const Node &other)
{
if (this != &other)
Copy(other);
return this;
}
template <typename T>
Node<T>& Node<T>::operator<<(const T &nodedata)
{
SetData(nodedata);
}
template <typename T>
bool Node<T>::operator==(const Node<T> &other)
{
return (data == other.data);
}
template <typename T>
bool Node<T>::operator<(const Node<T> &other)
{
return (data < other.data);
}
template <typename T>
bool Node<T>::operator>(const Node<T> &other)
{
return (data > other.data);
}
template <typename T>
bool Node<T>::operator<=(const Node<T> &other)
{
return (data < other.data || data == other.data);
}
template <typename T>
bool Node<T>::operator>=(const Node<T> &other)
{
return (data > other.data || data == other.data);
}
template <typename T>
bool Node<T>::operator!=(const Node<T> &other)
{
return (data != other.data);
}
template <typename T>
Node<T>::~Node()
{
NullPtrs();
}
template <typename T>
void Node<T>::SetData(const T &nodedata)
{
data = nodedata;
}
template <typename T>
void Node<T>::AddLeftChild(const Node<T> *leftchildptr)
{
leftchild = leftchildptr;
return;
}
template <typename T>
void Node<T>::AddRightChild(const Node<T> *rightchildptr)
{
rightchild = rightchildptr;
return;
}
template <typename U>
ostream& operator<<(ostream &out, Node<U> &node)
{
out << node.data;
return out;
}
template <typename T>
void Node<T>::Copy(const Node &other)
{
leftchild = other.leftchild;
rightchild = other.rightchild;
data = other.data;
}
#endif // NODE_H
Any help would be very much appreciated.
You're passing an rvalue (the constant 1) to Heap::AddToHeap(T &data), which takes a non-const reference. Change the function signature so it takes a const reference. You'll also have to propagate this to Heap<T>::AddToVacantNode(T &data) and any other relevant functions.
Here's an SO answer about const-correctness: Sell me on const correctness
You are calling AddToHeap with the literal 1. But your AddToHeap only accepts ints by reference. You can't pass the literal 1 by reference. If your AddToHeap function accepted the parameter by const reference, it would work.
void AddToHeap(const T& data);

error C2664 : 'void std::vector<_Ty>::push_back(_Ty&&)': cannot convert parameter 1 from 'Node<T> *' to 'Node<T>&&'

error C2664 : 'void std::vector<_Ty>::push_back(_Ty&&)': cannot convert parameter 1 from 'Node *' to 'Node&&'
please I need help...
I created node.h & heap.h
node.h :
#ifndef __NODE_H_
#define __NODE_H_
#include <string>
#include <iostream>
using namespace std;
template <class T>
class Node {
private:
Node<T>* m_brother;
int m_index;
T m_data;
public:
Node (T data);
~Node ();
int GetIndex () const;
int GetBrother () const;
void SetIndex (const int index);
void SetBrother (const Node<T>* brother);
void SetData (const T& data);
bool operator<(const Node<T>& other) const;
};
template <class T>
Node<T>::Node(T data) {
SetData(data);
}
template <class T>
int Node<T>::GetIndex () const {
return m_index;
}
template <class T>
int Node<T>::GetBrother () const {
return m_brother->GetIndex();
}
template <class T>
void Node<T>::SetData (const T& data) {
m_data = data;
}
template <class T>
void Node<T>::SetBrother(const Node<T>* brother) {
m_brother = brother;
}
template <class T>
void Node<T>::SetIndex(const int index) {
if (index > 0)
m_index = index;
else
cout <<"ERROR: Index Can't be negative number!"<<endl;
}
template <class T>
bool Node<T>:: operator<(const Node<T>& other)const
{
return *(this->GetData()) > *(other.GetData());
}
#endif
heap.h:
#ifndef __HEAP_H_
#define __HEAP_H_
#pragma once
#include <vector>
#include "Node.h"
using namespace std;
template<class T> class Heap {
public:
Heap();
virtual ~Heap();
Node<T> * CreateNode (T data);
bool IsEmpty() const;
Node<T>* RemoveNode(int indexNode);
Node<T>* ExtractMin ();
//void AddToHeap(Node<T>* newNode);
//void Add(int indexNode);
void Insert(Node<T>* newNode);
void DecreaseKey (Node<T>* newNode);
void Exchange (int indexNode1, int indexNode2);
void MinHeapify (int indexNode);
private:
vector<Node<T>> m_heap;
int num;
};
template<class T>
Heap<T>::Heap() {
}
template<class T>
Heap<T>::~Heap() {
}
template<class T>
Node<T>* Heap<T>::CreateNode(T data) {
Node<T*>* node(T);
return node;
}
template<class T>
bool Heap<T>::IsEmpty() const {
return (m_heap.size() == 0);
}
template<class T>
Node<T>* Heap<T>::RemoveNode (int indexNum) {
Node<T>* nodeToRemove=NULL;
if (indexNum > 0 && indexNum < m_heap.size()) {
nodeToRemove = m_heap[indexNum];
m_heap [indexNum] = m_heap [ m_heap.size()-1];
m_heap [m_heap.size()-1] = nodeToRemove;
m_heap.pop_back();
MinHeapify(nodeToRemove->GetIndex());
}
return nodeToRemove;
}
template<class T>
void Heap<T>::Insert(Node<T>* newNode) {
if (m_heap.size() == 0) {
m_heap.push_back(newNode);
}
else
DecreaseKey(newNode);
}
template<class T>
void Heap<T>::DecreaseKey(Node<T>* newNode) {
m_heap.push_back(newNode);
int index = m_heap.size();
while ((index > 0) && (m_heap[(index/2)-1] > m_heap[index-1])) {
Exchange(index,index/2);
index = index/2;
}
}
template<class T>
Node<T>* Heap<T>::ExtractMin () {
Node<T>* minNode;
minNode = m_heap[0];
m_heap[0] = m_heap[m_heap.size()-1];
m_heap.erase(m_heap[m_heap.size()-1]);
MinHeapify (0);
return minNode;
}
template<class T>
void Heap<T>::Exchange (int indexNode1, int indexNode2) {
Node<T>* tmp = m_heap[indexNode1-1];
m_heap[indexNode1-1] = m_heap [indexNode2-1];
m_heap[indexNode2-1] = tmp;
}
template<class T>
void Heap<T>::MinHeapify (int indexNode) {
int leftNode = 2*indexNode;
int rightNode = 2*indexNode+1;
int smallest = indexNode;
if ((leftNode < m_heap.size()-1) && (m_heap[leftNode-1]<m_heap[smallest-1]))
smallest = leftNode;
if ((rightNode < m_heap.size()-1) && (m_heap[rightNode-1]<m_heap[smallest-1]))
smallest = rightNode;
if (smallest != indexNode) {
Exchange (indexNode,smallest);
MinHeapify(smallest);
}
}
#endif;
In the main, I tried to check and it didn't compiled.
int main () {
Node<Vehicle*> a(car1);
Heap<Vehicle*> heap;
Node<Vehicle*>* p = &a;
heap.Insert(p);
return 0;
}
why?
Your Heap<T>::Insert function takes a Node<T*>*.
m_heap is defined as a vector<Node<T>>. You need to insert a Node<T*>, not a Node<T*>*. Heap<T>::Insert should take its parameter by const reference, not by pointer.
Your code uses a lot of pointers unnecessarily; it would be much simpler if you dealt with references and returned things by value rather than tangling with pointers all over the place.