Templated priority queue causing the object to become a pointer. c++ - c++

I'm trying to implement a templated priority queue using a heap to process frequencies of pixels in an image. It works fine, but when I try to use it by passing another class as the template argument, it ends up converting the class to a pointer to the class while trying to reheap down or up. Here is the heap specification:
template <typename ItemType>
struct HeapType
{
void ReheapDown(int, int);
void ReheapUp(int, int);
ItemType *elements;
int numElements;
};
reheap down function:
template<typename ItemType>
void HeapType<ItemType>::ReheapDown(int root, int bottom)
{
int maxChild, rightChild, leftChild;
leftChild = 2*root+1;
rightChild = 2*root+2;
if(leftChild <= bottom)
{
if(leftChild == bottom)
{
maxChild = leftChild;
}
else
{
if(elements[leftChild] <= elements[rightChild])
maxChild = rightChild;
else
maxChild = leftChild;
}
if(elements[root] < elements[maxChild])
{
Swap(elements, root, maxChild);
ReheapDown(maxChild, bottom);
}
}
}
and Swap funciton:
template<typename ItemType>
void Swap(ItemType &itemSwap, int swapFrom, int swapTo)
{
ItemType tempItem;
tempItem = itemSwap[swapFrom];
itemSwap[swapFrom] = itemSwap[swapTo];
itemSwap[swapTo] = tempItem;
}
So, I have the Priority queue being implemented using a helper class called Pfreq that overloads the comparison operators so that the heap sorts by frequency of the pixel rather than the value of the pixel. It has no problem until it gets to the Swap function and then complains that it can't convert the type from Pfreq to Pfreq*. I'm not entirely sure how to solve the problem that the template causes the Swap function to be called with type Pfreq*.

I think the issue is in the declaration of this function:
template<typename ItemType>
void Swap(ItemType &itemSwap, int swapFrom, int swapTo)
You're trying to use the first argument as an array, as evidenced here:
ItemType tempItem;
tempItem = itemSwap[swapFrom];
itemSwap[swapFrom] = itemSwap[swapTo];
itemSwap[swapTo] = tempItem;
The problem is that itemSwap is a reference to an ItemType, not an array of ItemTypes or a pointer to an ItemType. Try changing that parameter to be an ItemType* and see if that fixes things.
Hope this helps!

Related

deleting a object by calling a method it belongs

I have been learning and playing around C++ (mostly, pointers and dynamic memory allocation) for few days and I tried to create a generic class for linked list.
The classes
#include <cstdint>
#define _LINKEDLIST_DEFAULT_MAX_SIZE 2147483647L
template <typename T>
class LinkedList;
template <typename T>
class LinkedListNode;
template <typename T>
class LinkedListNode final
{
private:
LinkedListNode<T> *nextNode{nullptr};
friend LinkedList<T>;
public:
T data{};
};
template <typename T>
class LinkedList final
{
private:
LinkedListNode<T> *firstNode{nullptr};
std::int32_t maxLength{};
std::int32_t currentLength{};
public:
LinkedList(std::int32_t max_size = _LINKEDLIST_DEFAULT_MAX_SIZE)
{
maxLength = max_size;
}
void addFirst(LinkedListNode<T> *nodePtr)
{
if (firstNode == nullptr)
{
firstNode = nodePtr;
return;
}
nodePtr->nextNode = firstNode;
firstNode = nodePtr;
}
void clerList()
{
// code of releasing occupied heap memory back
}
}
Main method
int main()
{
LinkedList<short> *head{new LinkedList<short>()};
LinkedListNode<short> *node1{new LinkedListNode<short>()};
LinkedListNode<short> *node2{new LinkedListNode<short>()};
node1->data = 1;
node2->data = 2;
head->addFirst(node1);
head->addFirst(node2);
return 0;
}
And this works as properly so far as variables in my debugger shows expected results.
But my issue is how could I write my clearList() method on LinkedList<T> class? I can traverse through LinkedListNode<T> objects and release their memory back calling delete(), but calling delete(this) from clearList() to release back the memory of LinkedList<T> object at first sounds like suiciding since it tries to delete the object which it belongs to. (Note that some simple validation logics have not yet been put into the code)
Do you have any ideas to make this happen :)

destructor for array of linked lists

I'm having trouble figuring out the destructor for my hashTable class, the destructor is like this:
template <typename ElementType>
HashSet<ElementType>::~HashSet() noexcept
{
for (unsigned int i=0;i<hashCapacity;i++)
{
Node* current = hashTable[i];
while(current != nullptr)
{
Node* entry = current;
current = current->next;
delete[] entry;
}
}
delete[] hashTable;
}
No matter I use either delete[] or delete, it gives me either double-free errors or segmentation fault.
The class template is below:
template <typename ElementType>
class HashSet : public Set<ElementType>
{
public:
// The default capacity of the HashSet before anything has been
// added to it.
static constexpr unsigned int DEFAULT_CAPACITY = 10;
// A HashFunction is a function that takes a reference to a const
// ElementType and returns an unsigned int.
using HashFunction = std::function<unsigned int(const ElementType&)>;
public:
// Initializes a HashSet to be empty so that it will use the given
// hash function whenever it needs to hash an element.
explicit HashSet(HashFunction hashFunction);
// Cleans up the HashSet so that it leaks no memory.
~HashSet() noexcept override;
// add() adds an element to the set. If the element is already in the set,
// this function has no effect. This function triggers a resizing of the
// array when the ratio of size to capacity would exceed 0.8, in which case
// the new capacity should be determined by this formula:
//
// capacity * 2 + 1
//
// In the case where the array is resized, this function runs in linear
// time (with respect to the number of elements, assuming a good hash
// function); otherwise, it runs in constant time (again, assuming a good
// hash function). The amortized running time is also constant.
void add(const ElementType& element) override;
Where my add function and default constructor implementation is like this:
template <typename ElementType>
HashSet<ElementType>::HashSet(HashFunction hashFunction)
: hashFunction{hashFunction}
{
hashCapacity = DEFAULT_CAPACITY;
hashSize = 0;
hashTable = new Node* [hashCapacity];
for (int i=0;i<hashCapacity;++i)
{
hashTable[i] = nullptr;
}
}
template <typename ElementType>
void HashSet<ElementType>::add(const ElementType& element)
{
if (contains(element)==false)
{
if ((hashSize/hashCapacity) > 0.8)
{
}
else
{
unsigned int index = hashFunction(element) % hashCapacity;
hashSize += 1;
Node* add = new Node;
add->next = nullptr;
add->value = element;
if (hashTable[index]==nullptr)
{
hashTable[index] = add;
}
else
{
Node* addNode = hashTable[index];
while(addNode->next != nullptr)
{
addNode = addNode->next;
}
addNode->next = add;
}
}
}
}
Note: that resize hashtable part is incomplete because I'm examining the functionality for my hash table to hold a small amount of value first.

Huffman coding and priority queue

I had an assignment today and I'm really struggling trying to find a solution.
"Using a Binary-Search-Tree based priority queue, implement Huffman Coding [...]".
So, basically, I have to write my own priority queue based on a Binary Search Tree.
I managed to get a working BST and so on, but I've been really smashing my head against every wall In my room for the last two-tree days for the second part.
And that's Huffman's fault (Just kidding, I know I'm kinda stupid).
In Huffman Algorithm, we create a priority queue, fill it with our N starting elements, then we pop() the 2 nodes with minimum frequences, create a new node whose frequence is the sum of the previously popped elements and push() that node into the priority queue and reiterate[...].
To make my BST into a priority queue, I added one member and two methods: min,getMin() and extractMin().
min is a pointer to the node whose value is the lowest in the tree.
getMin() is a method that starts from a given node, and looks for the minimum value in its left subtree.
Please, note that everytime a node gets removed or a new node inserted, it calls an update of the min variable of the tree (a new inserted node could have a lower value than the previous min, so mingets updated, and the node pointer by min could be removed, somin gets updated).
extractMin() is basically a wrapper for pQueue.remove(pQueue.getMin()).
The thing is this: after popping the two elements with lowest frequency, and creating the new node, inserting it in the tree causes a min update. Since the left and right members of the new inserted node have a lower frequence than the inserted note itself, the min variable is set to one of those two members. I am struggling to find a solution to this. I don't want code or lines, I just want some ideas because I really ran out of patience and intelligence.
Following, my BST class and a snippet of the Huffman code I wrote. Please, be kind, I'm new to coding.
template <class T>
class BST
{
private:
void setRoot(bstNode<T>* nd){this->root=nd;}
bool isEmpty()const{if (this->getRoot()==nullptr) return true; else return false;}
protected:
bstNode<T>* root;
bstNode<T>* min;
public:
BST(void){this->root=nullptr;this->min=nullptr;}
BST(bstNode<T>* rt){this->root=rt;}
~BST(void){this->root=nullptr;};
void inorder(bstNode<T>*) const;
void insert(bstNode<T>*);
bool remove(bstNode<T>*);
void extractMin();
bstNode<T>* getRoot()const {return this->root;}
bstNode<T>* getMin(bstNode<T>*)const;
bstNode<T>* getMin()const {return this->min;} //simply returns a pointer to the minimum
void setMin(bstNode<T>* nd){this->min=nd;}
};
template <class T>
void BST<T>::extractMin()
{
if (this->getMin()!=nullptr)
this->remove(this->getMin());
else return;
}
template <class T>
void BST<T>::insert(bstNode<T>* nd)
{
if (this->isEmpty()==true)
{
this->setRoot(nd);
this->setMin(nd);
return;
}
else
{
bstNode<T>* up=nullptr;
bstNode<T>* actual=this->getRoot();
while (actual!=nullptr)
{
up=actual;
if(nd->getValue()<=actual->getValue())
actual=actual->getLeft();
else actual=actual->getRight();
}
nd->setParent(up);
if (nd->getValue()<=up->getValue())
up->setLeft(nd);
else up->setRight(nd);
}
if (nd->getValue()<=this->getMin()->getValue())
this->setMin(nd);
}
template <class T>
bool BST<T>::remove(bstNode<T>* nd)
{
if (nd==this->getMin())
this->setMin(nullptr);
if (nd==this->getRoot() && nd->getRight()==nullptr && nd->getLeft()==nullptr)
{
this->setRoot(nullptr);
return true;
}
if (nd==this->getRoot() && nd->getRight()!=nullptr)
this->setRoot(nd->getRight());
else if( nd==this->getRoot() && nd->getLeft()!=nullptr)
this->setRoot(nd->getLeft());
bstNode<T>* Root=this->getRoot();
bstNode<T>* temp, *temp2;;
if (nd->getLeft()==nullptr)
this->swapTree(Root,nd,nd->getRight());
else if (nd->getRight()==nullptr)
this->swapTree(Root,nd,nd->getLeft());
else
{
temp=this->getMin(nd->getRight());
if (temp->getParent()!=nd)
{
this->swapTree(Root,temp,temp->getRight());
temp->setRight(nd->getRight());
temp2=temp->getRight();
temp2->setParent(temp);
}
this->swapTree(Root,nd,temp);
temp->setLeft(nd->getLeft());
temp2=temp->getLeft();
temp2->setParent(temp);
}
this->setMin(this->getMin(this->getRoot()));
return true;
}
template <class T>
bstNode<T>* BST<T>::getMin(bstNode<T>* nd)const //find and return the minimum of the tree whose root is nd
{
while (nd->getLeft()!=nullptr)
nd=nd->getLeft();
return nd;
}
and here's the Huffman part:
template <class T>
class Encoder
{
private:
std::vector <myTuple> *alphabet; //vector of tuples <fequency,character, isInternal>
void createPqueue();
void createAlphabet();
void encode();
void showHuff(bstNode<T>*, string);
BST<T> *hTree;
public:
Encoder(){createAlphabet();createPqueue();};
~Encoder(){};
std::vector <myTuple> * getAlphabet()const{return this- >alphabet;}
BST<T> *getPqueue()const{return this->hTree;}
void askWhat();
};
template <class T>
void Encoder<T>::createPqueue()
{
this->hTree=new BST<myTuple>();
if (this->hTree==nullptr)
{
cout<<"Error allocating Red-Black Tree, now exiting..."<<endl;
exit(-1);
}
}
for (unsigned int i = 0; i < this->getAlphabet()->size(); ++i)
{
bstNode<myTuple>* temp;
temp=new bstNode<myTuple>(this->getAlphabet()->at(i));
if (temp!=nullptr)
this->getPqueue()->insert(temp); //fill the priority Queue with <int frequency, char character, bool is_internal> Nodes. I still have to remove tuples since they are not necessary anymore.
else
exit(-1);
}
bstNode<myTuple> *left, *right, *top;
for (unsigned int i = 0; i< u_int(this->getAlphabet()->size())-2;i++)
{
left=this->getPqueue()->getMin();
this->getPqueue()->extractMin();
right=this->getPqueue()->getMin();
this->getPqueue()->extractMin();
myTuple temp ((get<0>( left->getValue() ) + get<0>( right->getValue() )),'\0',true);
top=new bstNode<myTuple>(temp);
if (top==nullptr)
{
cout <<"Can't allocate top, now exiting..."<<endl;
exit(-1);
}
top->setLeft(left);
top->setRight(right);
this->getPqueue()->insert(top);
}
I've been using the bool value in tuples to distinguish between internal and external nodes, but with no success.
Thank you in advance and I'm really sorry if I've been messy, my clearness equals my state of mind as of now. Thank you.

Reversing a generic doubly-linked list in C++

I'm trying to give my generic list class a reverse function. For some reason, my algorithm ain't workin' when I test it. I thought it made sense: swap the pointers to the first and last nodes of the list, then go through the list and for each node swap its pointers to the previous and next node.
Go easy on me, guys. I'm trying to get some practice with generic programming. Teach me the ways of a C++ purist.
Here's the swap function:
template <class T> void swap(T* a, T* b) {
T* tempPtr = a;
a = b;
b = tempPtr;
}
Here's the reverse function:
template <class T> void List<T>::reverse() {
if (size > 1) {
swap(firstNodePtr, lastNodePtr);
node* curNodePtr = firstNodePtr;
while (curNodePtr != NULL) {
swap(curNodePtr->prevNodePtr, curNodePtr->nextNodePtr);
curNodePtr = curNodePtr->nextNodePtr;
}
}
}
Here's the class, its members and prototypes for functions:
template <class T> class List {
public:
List();
~List();
void push_back(T);
void push_front(T);
T get_at(unsigned);
unsigned get_size();
void reverse();
private:
struct node {
T val;
node* prevNodePtr;
node* nextNodePtr;
};
node* firstNodePtr;
node* lastNodePtr;
unsigned size;
};
Your swap<T> function does not work: it exchanges pointers, which are copied by value into local variables of your function, which has no effect in the caller.
Dropping your own swap and replacing it with std::swap will fix this problem.
Since you pass the two pointers by value, the changes to a and b don't propagate out of the swap() function, making it a no-op.
One way to fix it is by passing the pointers by reference:
template <class T> void swap(T*& a, T*& b) {
Alternatively (and preferably) just use std::swap() instead of your own function.
If you exposed your node structure (or at least a bidirectional iterator type for your list), you could avoid the whole issue and just use std::reverse.
List<int> someList;
// fill with data
std::reverse(someList.begin(), someList.end()); // where begin returns a bidirectional iterator for the head, and end returns a bidirectional iterator for 1 element beyond the tail

How to use a single Template statement for more than one function or struct?

I've been trying to represent Stacks as a template, I used a struct and every thing is good, but every time I wanted to write a template function, I had to write the same template statement, which didn't seem correct -although working-
So how can I write one template statement for all the functions?, here is my code :
template &#60typename T>
struct Stack
{
T Value;
Stack* next;
};
template &#60typename T>
void Push(T Value,Stack* &Top)
{
Stack * Cell = new Stack();
Cell->Value = Value;
Cell->next = Top;
Top = Cell;
};
template &#60typename T>
bool IsEmpty(Stack * Top)
{
return (Top==0);
}
template &#60typename T>
void Pop(T &Value,Stack* &Top)
{
if (IsEmpty(Top))
cout * Temp = Top;
Value = Top->Value;
Top = Top->next;
delete Temp;
}
}
template &#60typename T>
void GetTop(T &Value, Stack* &Top)
{
if (IsEmpty(Top))
cout Value;
}
template &#60typename T>
void EmptyStack(Stack * &Top)
{
Stack * Temp;
while (!(IsEmpty(Top)))
{
Temp = Top;
Top = Top->next;
delete Temp;
}
}
Hope what I mean is clear now, sorry for the slight question :(
thanks in advance.
If (as appears to be the case based on your comment) you want them as free functions, you can't. You'll also have to change the Stack parameter, something like this:
template <typename T>
void Push(T Value, Stack<T>* &Top)
{
Stack * Cell = new Stack();
Cell->Value = Value;
Cell->next = Top;
Top = Cell;
};
As it stands, I'm not too excited about your design though. You try to use the Stack type as both an actual stack, and as a single node (Cell) in the stack. This is unnecessarily confusing at best.
Edit: As far as stack vs. node goes, what I'm talking about is (as in the code immediately above): Stack *Cell = new Stack(); -- you're allocating a single Cell that goes in the stack, but the type you're using for it is Stack.
I'd do something like this instead:
template <class T>
struct Stack {
struct node {
T data;
node *next;
};
node *head;
};
template <class T>
void push(T item, Stack<T> *&s) {
Stack<T>::node *n = new Stack<T>:node();
n->data = item;
n->next = s->head;
s->head = n;
}
It doesn't make a lot of difference in what you're really doing, but when you're putting something onto a stack, allocating a Stack<T>::node seems (at least to me) to make a lot more sense than allocating a Stack<T>. A stack containing multiple nodes makes sense -- a Stack containing multiple stacks really doesn't.
You could simply write a template class instead, and write all those functions as methods of that class. They will then share the same template parameters as the class.