Queue appending more then one entry - c++

I keep getting the first entry appended 4 times instead of one time.. when I append my first entry to the Queue it appends it 4 times..I thought this might be the problem..but it looks like it isn't. I can't find where the problem is..
I also created a print function for the nodes, and it showes that there are 4 of the same entries in the queue, so it is not a printing problem. And it doesn't look like it's in the read function. Maybe it's in the logic of the append function?? Still working on it..
This is the output: 3X^2 + 3X^2 + 3X^2 + 3X^2 + 1 but it should be 3X^2 + 1
This is my append function:
//Append(Add) item to back of queue.
Error_code Extended_queue::append(const Queue_entry &item) {
Node<Queue_entry> *new_rear = new Node<Queue_entry>(item);
if(rear == nullptr){
front = new_rear; // I also tried rear = new_rear; front = rear; rear = new_rear;
}
else {
rear->next = new_rear;
rear = new_rear;
}
return success;
}
And here is the code that prints the output:
This is the node code declaration:
#ifndef NODE_H
#define NODE_H
enum Error_code{success,underflow,overflow}; // Used in node containing classes
template <class Node_entry> // Template to allow for more varience
// Part of a linked structure
struct __declspec(align(1)) Node{
Node_entry entry; // Data contained in the node
Node *next; //Pointer to next node
//constructors
Node(); // Creates empty node
Node(Node_entry item, Node *add_on = nullptr); // Creates node with specified data and pointer to next node
};
/* Post: The Node is initialized to contain nothing, and to have a null pointer.*/
template <class Node_entry>
Node<Node_entry>::Node()
{
entry = nullptr;
next = nullptr;
}
/* Post: The Node is initialized to contain item, and to point to add_on.*/
template <class Node_entry>
Node<Node_entry>::Node(Node_entry item, Node *add_on)
{
entry = item;
next = add_on;
}
#endif

It looks like the copy constructor had bad logic. After I fixed th constructor, the driver only returned the first term as front and rear entry. So I had to fix up the overloaded = operator as well.
New Code(for copy constructor):
Extended_queue::Extended_queue(const Extended_queue &original){
Node<Queue_entry> *temp_node, *original_node = original.front;
if(original.empty()){ //original queue is empty, set new to NULL
front = nullptr;
rear = nullptr;
}
else
{
front = temp_node = new Node<Queue_entry>(original_node->entry,nullptr);
while(original_node->next != nullptr)
{
original_node = original_node->next;
//needed to change next and still incriment
temp_node->next = new Node<Queue_entry>(original_node->entry, nullptr);
temp_node = temp_node->next;
//rear->next = temp_node;
//rear = temp_node;
}
rear = temp_node->next;
}
}

Related

c++ linked list, removing element disconnects the rest of the list

I was trying to implement this simple linked list project for my homework. When I tried to implement the removeByKey function, I ran into the problem that it disconnects the rest of the list entirely when it finds the key to be removed.
Here's the class:
class LancElem
{
private:
int key;
LancElem* next;
public:
LancElem(){next = nullptr;}
LancElem(int keyy, LancElem* nextt){key = keyy;next = nextt;}
LancElem* getNext(){return next;}
int getKey(){return key;}
void setNext(LancElem* nextt){next = nextt; }
void setKey(int keyy){key = keyy;}
};
The remove fucntion:
void removeByKey(LancElem& head, int key){
LancElem* n = head.getNext();
while(n->getNext()!=nullptr){
if(n->getNext()->getKey()==key){
n->setNext(n->getNext()->getNext());
delete n->getNext();
break;
}
n=n->getNext();
}
}
When I try to remove the biggest element:
The original linked list: 4 1 9 8 2 7 3 6 3
Expected output: 4 1 8 2 7 3 6 3
The real output: 4 1 0
The problem is probably where I connect the current element to the next->next element but I can't figure out why my implementation isn't good.
Ask yourself:
What is n->next after the line n->setNext(n->getNext()->getNext()); ? What does the line delete n->getNext(); delete?
You don't want to delete the just updated next but you want to delete the to be removed element:
auto to_be_deleted = n->getNext();
n->setNext(to_be_deleted->getNext());
delete to_be_deleted;
It seems your list has a dummy head node that does not have a value.
The function removeByKey can invoke undefined behavior when head.getNext() returns a null pointer due to using the expression n->getNext()
LancElem* n = head.getNext();
while(n->getNext()!=nullptr){
Also within the if statement
if(n->getNext()->getKey()==key){
n->setNext(n->getNext()->getNext());
delete n->getNext();
break;
}
you are trying to delete a node after the node to be deleted due to preceding assignment of the data member next by using the function setNext.
n->setNext(n->getNext()->getNext());
delete n->getNext();
Pay attention to that your function is unable to delete the node after the dummy head node due to using by you two times the call of getNext()
LancElem* n = head.getNext(); // the first call of getNext
while(n->getNext()!=nullptr){
if(n->getNext()->getKey()==key){ // the second call of getNext.
//...
The function can be defined like
void removeByKey( LancElem &head, int key )
{
if ( head.getNext() != nullptr )
{
if ( head.getNext()->getKey() == key )
{
LancElem *current = head.getNext();
head.setNext( head.getNext()->getNext() );
delete current;
}
else
{
LancElem *n = head.getNext();
while( n->getNext() != nullptr && n->getNext()->getKey() != key )
{
n = n->getNext();
}
if ( n->getNext() != nullptr )
{
LancElem *current = n->getNext();
n->setNext( n->getNext()->getNext() );
delete current;
}
}
}
}
Now try to use this function to delete the first node with the value 4 of your list and the function you currently have and compare their results.

Selection sort in single linked list without using swap

I have been trying to solve the selection sort in single linked list without using swap nodes. Using a temp list to store nodes and assign the current list with a new one
//my addlastnode function
void AddLastNODE(LIST &mylist, NODE *p)
{
//Check the list is empty or not
if(isEmpty(mylist))
mylist.pHead = mylist.pTail = p;
else
mylist.pTail->pNext = p;
mylist.pTail = p;
}
void selectionSort(LIST &mylist)
{
//Initialize a temp list to store nodes
LIST mylisttemp;
IntList(mylisttemp);
//Create node
NODE *p;
NODE *i;
//Create min node
NODE *min;
//Check if list is empty or has one node
if(mylist.pHead == mylist.pTail)
return;
//Traverse the list till the last node
for(p=mylist.pHead; p->pNext!=NULL && p!=NULL; p = p->pNext)
{
min=p;
for(i=p->pNext; i!=NULL;i=i->pNext)
{
////Find the smallest data in list
if(i->data < min->data)
min=i;
}
////Add the smallest to a new list
AddLastNODE(mylisttemp, min);
}
//Fill the current list to the new list
if(!isEmpty(mylisttemp))
mylist = mylisttemp;
}
Your code does not reduce the list you are selecting nodes from: the selected node should be removed from it. To make that happen, you need a reference to the node before the selected node, so that you can rewire the list to exclude that selected node.
There is also a small issue in your AddLastNODE function: it does not force the tail node to have a null as pNext pointer. This may be a cause of errors when the function is called with a node that still has a non-null pNext pointer. Secondly, the indentation is off around the else block. It does not lead to a bug in this case, but still it is better to avoid the confusion:
void AddLastNODE(LIST &mylist, NODE *p)
{
if(isEmpty(mylist))
mylist.pHead = p;
else
mylist.pTail->pNext = p;
mylist.pTail = p; // indentation!
p->pNext = nullptr; // <--- better safe than sorry!
}
Then to the main algorithm. It is quite tedious to work with a previous node reference when looking for the node with the minimum value. It helps a bit when you temporarily make the input list cyclic:
void selectionSort(LIST &mylist) {
if (mylist.pHead == mylist.pTail) return;
// Make list temporarily cyclic
mylist.pTail->pNext = mylist.pHead;
LIST mytemplist;
IntList(mytemplist);
while (mylist.pHead != mylist.pTail) {
// Select node:
NODE * beforemin = mylist.pTail;
for (NODE * prev = mylist.pHead; prev != mylist.pTail; prev = prev->pNext) {
if (prev->pNext->data < beforemin->pNext->data) {
beforemin = prev;
}
}
NODE * min = beforemin->pNext;
// Extract selected node:
if (min == mylist.pTail) mylist.pTail = beforemin;
if (min == mylist.pHead) mylist.pHead = min->pNext;
beforemin->pNext = min->pNext;
// And insert it:
AddLastNODE(mytemplist, min);
}
// Move last remaining node
AddLastNODE(mytemplist, mylist.pHead);
// Copy back
mylist = mytemplist;
}
As a side note: You might even want to always keep your list cyclic. This will mean some changes in other functions you may have, as there will be no pNext pointers that are null then.

How to pass pointers correctly for custom class

The backPtr_ of last node is pointing to itself at the time of generating trajectory.
This is mostly happening due to the backptr__ is pointing at the back of openNodes and while exploring a node it is last element due to pop_heap.
Any work around for this?
I have already tried to keep the openNodes as vector of Node objects rather than of pointers.
init_node.calculateF();
vector<Node*> openNodes;
openNodes.push_back(&init_node);
vector<vector<coord_t>> traj;
while(!openNodes.empty()){
pop_heap(openNodes.begin(), openNodes.end(), NodePtrCompareGtr());
Node* newNodePtr = openNodes.back();
Node newNode = *newNodePtr;
openNodes.pop_back();
traj = newNode.exploreNodes(openNodes, openSet, closedNodes, &newNode);
}
class Node
{
Node *backPtr_ = NULL;
public:
void setBackPtr(Node* nodeptr){
backPtr_ = nodeptr;
}
vector<vector<coord_t>> exploreNodes(vector<Node*> &openNodes){
newCoordList = generateCoords();
vector<Node*> newNodeList;
if(goal_reached(this)){
return generate_traj(this);
}
for(auto const& newCoords : newCoordsList){
Node *newNode = new Node(...);
newNodeList.push_back(newNode);
}
for(auto & i : newNodeList){
...
i->setBackPtr(this);
openNodes.push_back(i);
make_heap(openNodes.begin(), openNodes.end(), NodePtrCompareGtr());
...
}
}
I want to store the backPtr_ correctly to store the correct previous node.

Dequeue function not outputting proper values

There seems to be an issue with my dequeue function within a queue class that I have. My dequeue function which is part of the position class, is not returning the correct values that have been enqueued into the list.
The values that have been enqueued are which is a position object, are 2,1 and -1, but when I dequeue that object i get 2,506216, and -1; When I assign the *pos ponter to an object I am left with the default values;The enqueue function seems to be working correctly for when I check the ptr values they are correct.
//position constructor
front = back = &header;
struct Posnode
{
Position *pos;
Posnode *next;
};
class Position
private:
Posnode *front,*back,header;
void Position::dequeue(Position&p)
{
Posnode *ptr=front->next;
front->next = ptr->next;
p = *ptr->pos;
p.geta();//checking for values but am left with the default
if (back == ptr)
{
back = front;
}
delete ptr;
}
v
oid Position::enqueue(Position n) //assigning Position object to end of queue
{
Posnode *ptr = new Posnode;
ptr-> pos = &n;
back->next = ptr;
back = ptr;
return;
}
Position copy,intial(5);
copy = intial;
if (copy.ismovelegal(posmoves, r))
{
copy.makemove(posmoves, r);
if (intial.solved(copy))
{
cin.get();
}
else
{
p.enqueue(copy);
}
}
copy.free();//clearing object private memebers
}
intial.free();
p.dequeue(o);//copy that was previous enqued is not enqued
o.geta();
Just Check out the Implementation of Deque first and then try your own. If its some syntax or semantic error post minimal code that reproduces your code.
this link might help you. Deque Implementation

Interview Coding - Take a pointer to a Node structure as a parameter and return a complete copy of the passed-in data structure

This is an interview question that I found interesting.
Write a method that takes a pointer to a Node structure as a parameter and returns a complete copy of the passed-in data structure.
The Node structure contains two pointers to other Node structures.
For example, the method signature could look like so:
Node* Copy(Node* root);
Note - Do not make any assumptions about the data structure – it could be a tree, linked list, graph, etc.
How can this be done for any data structure ?
In the generic graph case, you need a mapping from nodes in the original graph to nodes in the new graph, so that when a cycle is encountered, the proper link gets created. If you happen to have extra temporary space in each node, large enough to hold a pointer, then you can store the mapping directly in the nodes; otherwise, you'll need to use an external map, such as an associative array or hash table.
Then it's just a matter of traversing the graph, copying nodes, and looking up the corresponding edges. Something like this:
struct Node
{
Node(int _data) : data(_data) { memset(links, 0, sizeof(links)); }
int data;
Node *links[2];
}
Node *Copy(Node *root)
{
typedef std::map<Node*, Node*> NodeMap;
NodeMap nodeMap;
std::deque<Node*> nodesToVisit;
// Set up initial new root and mapping for the root
Node *newRoot = new Node(root->data);
nodeMap[root] = newRoot;
// Breadth-first search the graph
nodesToVisit.push_back(root);
while(!nodesToVisit.empty())
{
Node *cur = nodesToVisit.front();
nodesToVisit.pop_front();
Node *newCur = nodeMap[cur];
for(int i = 0; i < 2; i++)
{
Node *link = cur->links[i];
if(link)
{
// If we've already created the corresponding node for this
// link, use that. Otherwise, create it and add it to the map.
NodeMap::iterator mappedLink = nodeMap.find(link);
if(mappedLink != nodeMap.end())
{
newCur->links[i] = mappedLink->second;
}
else
{
Node *newLink = new Node(link->data);
nodeMap[link] = newLink;
newCur->links[i] = newLink;
nodesToVisit.push_back(link);
}
}
}
}
return newRoot;
}
The problem as stated is impossible. You have to assume that the entire data structure is stored entirely within the content of nodes that are accessible from that initial one. But that is not an assumption you are allowed to make. Even your standard basic double linked list might not fit that description.
class Copier {
std::map <Node*, Node*> copies;
Node* Copy(Node* n) {
if (!n) return 0;
Node*& copy = copies[n];
if (!copy) {
copy = new Node();
copy.node1 = Copy(n.node1);
copy.node2 = Copy(n.node2);
}
return copy;
}
}
Node* Copy(Node* root) {
if (root == NULL)
return root;
std::unordered_map<Node*, Node*> completed;
std::deque<Node*> todo;
Node *ret = new Node(*scur);
completed.push_back(std::make_pair(root, ret));
todo.push_pack(root);
//while there's more nodes to duplicate
do {
//duplicate the node
Node* oldNode = todo.back();
Node* newNode = completed[cur];
todo.pop_back();
if(oldNode->left) {
auto iter = completed.find(oldNode->left);
//if it has a left child that needs duplicating, add it to the todo list
if (iter == completed.end()) {
newNode->left = new Node(*(oldNode->left));
completed.push_back(std::make_pair(oldNode->left, newNode->left));
todo.push_back(oldNode->left);
} else {
newNode->left = completed[oldNode->left];
}
}
if(oldNode->right) {
auto iter = completed.find(oldNode->right);
//if it has a right child that needs duplicating, add it to the todo list
if (iter == completed.end()) {
newNode->right = new Node(*(oldNode->right));
completed.push_back(std::make_pair(oldNode->right, newNode->right));
todo.push_back(oldNode->right);
} else {
newNode->right= completed[oldNode->right];
}
}
} while(todo.empty() == false)
//return the translation of the root
return ret;
}
Doesn't have stack overflow, root can be NULL, doesn't fail if left or right are NULL.
[Edit]Adam Rosenfield made me realize this was incorrect if there was loops in the network. Had to rewrite almost from scratch. Due to the large amount of code required, I prefer his code's for loop.
return new Node(*node);
Trick question?
You should write it recursively;
Node * Copy( Node * root )
{
Node * node_copy;
node_copy = new Node; // Assume Node1 and Node2 are initialized to 0
node_copy->content = root->content;
if( root->Node1 ) node_copy->Node1 = Copy( root->Node1 );
if( root->Node2 ) node_copy->Node2 = Copy( root->Node2 );
return node_copy;
}
So, this does not make any assumption on the data type
Given that a copy constructor exists that copies only the contents of a node and not its children:
Node* Copy(Node* root)
{
Node* copy = new Node(*root);
copy->left = Copy(root->left);
copy->right = Copy(root->right);
return copy;
}
In a more general sense, I would use copy-constructors that fully copy the entire data structure:
Node* Copy(Node* root)
{
return new Node(*root);
}