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);
Related
linkedlist.h
#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_
#include <iostream>
template <typename T>
class list{
public:
list();
class node;
typedef T value_type;
typedef T& reference;
typedef node node_type;
typedef node_type* node_pointer;
list& push_back(value_type);
value_type pop_front();
node_pointer begin() const;
private:
node_pointer head, tail;
};
template <typename T>
class list<T>::node{
public:
node(value_type value = 0);
void setData(value_type);
value_type getData() const;
void setNext(node_pointer);
node_pointer getNext() const;
private:
value_type data;
node_pointer ptr_next;
};
template <typename T>
inline list<T>::node::node(value_type value) : data(value), ptr_next(nullptr){
}
template <typename T>
void list<T>::node::setData(value_type value){
this->data = value;
}
template <typename T>
typename list<T>::value_type list<T>::node::getData() const{
return this->data;
}
template <typename T>
void list<T>::node::setNext(node_pointer ptr){
this->ptr_next = ptr;
}
template <typename T>
typename list<T>::node_pointer list<T>::node::getNext() const{
return this->ptr_next;
}
template <typename T>
list<T>::list() : head(nullptr), tail(nullptr){
}
template <typename T>
list<T>& list<T>::push_back(value_type value){
node_pointer item = new node_type(value);
if(this->tail) this->tail->setNext(item);
this->tail = item;
if(!this->head) this->head = this->tail;
return *this;
}
template <typename T>
typename list<T>::value_type list<T>::pop_front(){
if(this->head){
node_pointer item = this->head;
value_type value = this->head->getData();
this->head = this->head->getNext();
delete item;
return value;
}
return 0;
}
template <typename T>
typename list<T>::node_pointer list<T>::begin() const{
return this->head;
}
template <typename T>
std::ostream & operator<<(std::ostream &stream, list<T> &obj){
typename list<T>::node_pointer ptr = obj.begin();
while(ptr->getNext() != nullptr){
stream << ptr->getData() << " ";
ptr->setNext(ptr->getNext());
}
return stream;
}
#endif /* LINKEDLIST_H_ */
main.cpp
#include <iostream>
#include "LinkedList.h"
using std::cout;
using std::endl;
int main (int argc, char ** argv){
list<int> mylist;
mylist.push_back(5).push_back(1);
cout << mylist;
return 0;
}
I just wanted to create a print function which overloads operator<<. whatever i did, i couldn't find the solution. What is the wrong with this overloaded operator<< function? And how can i clean garbage if program throws error. How destructor function should be?
template <typename T>
std::ostream & operator<<(std::ostream &stream, list<T> &obj){
typename list<T>::node_pointer ptr = obj.begin();
while(ptr != nullptr){
stream << ptr->getData() << " ";
ptr = ptr->getNext();
}
return stream;
}
i realized that i made a logical mistake during the print function. But i still wonder how to collect garbage?
I get this error when I try to compile either popRight or popLeft. Why? Here are the codes.
Dequeue class
#include "node.h"
template <class T>
class Dequeue
{
public:
void pushLeft(T data);
void popLeft();
T left();
void pushRight(T data);
void popRight();
T right();
bool empty();
private:
int length;
};
template<typename T>
bool Dequeue<T>::empty()
{
if (length == 0)
{
return true;
}
else
return false;
}
template<typename T>
void Dequeue<T>::pushLeft(T data)
{
if (empty() == true)
{
left->setData(data);
right->setData(data);
}
else if (left->getData() == right->getData())
{
left->setData(data);
}
else
{
node<T> *aux = new node<T>;
aux->setData(data);
left->setPrevious(aux);
aux->setNext(left);
left = aux;
}
length++;
}
template<typename T>
void Dequeue<T>::pushRight(T data)
{
if (empty() == true)
{
right->setData(data);
left->setData(data);
}
else if (right->getData() == left->getData())
{
right->setData(data);
}
else
{
node<T> *aux = new node<T>;
aux->setData(data);
right->setPrevious(aux);
aux->setNext(right);
right = aux;
}
length++;
}
template<typename T>
void Dequeue<T>::popLeft()
{
node<T> *node = left->getNext();
node->setPrevious(NULL);
left = node;
}
template<typename T>
void Dequeue<T>::popRight()
{
node<T> *node = right->getPrevious();
node->setNext(NULL);
right = node;
}
Node Class
template <class T>
class node
{
public:
node(T data);
node(T data, node<T>* next);
T getData();
node<T>* getNext();
void setData(T data);
void setNext(node<T>* next);
void setPrevious(node<T>* previous);
private:
T data;
node<T> *next;
node<T> *previous;
node<T> *left;
node<T> *right;
};
template <typename T>
node<T>::node(T data)
{
this->data = data;
this->next = NULL;
this->previous = NULL;
}
template <typename T>
node<T>::node(T data, node<T>* next)
{
this->data = data;
this->next = next;
this->previous = previous;
}
template <typename T>
T node<T>::getData()
{
return this->data;
}
template <typename T>
node<T>* node<T>::getNext()
{
return this->next;
}
template <typename T>
void node<T>::setData(T data)
{
this->data=data;
}
template <typename T>
void node<T>::setNext(node<T>* next)
{
this->next = next;
}
template <typename T>
void node<T>::setPrevious(node<T>* previous)
{
this->previous = previous;
}
Ive been trying to solve this problem for like an hour but I just can't, can anyone help?
You declared left and right as functions. But it's clear from the way you use them in the rest of the code that they should be variables.
class Dequeue
{
public:
void pushLeft(T data);
void popLeft();
T left;
void pushRight(T data);
void popRight();
T right;
bool empty();
private:
int length;
};
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.
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.
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.