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
Related
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.
Hi this is a code from my SearchTree class.
Node* is a structure whith m_info type int, and m_left(smaller nodes by info) and m_right(bigger nodes by info)
void SearchTree::insert(const int &x) {
Node* tempo = m_root;
while (tempo != nullptr) {
if (tempo->m_info >= x) {
tempo = tempo->m_left;
} else {
tempo = tempo->m_right;
}
}
tempo = new Node(x);
}
I am trying to insert a new node to the tree.
But looks like I am missing something in memory management.
There tempo is a pointer to a new node, however it is not being related to m_root.
I am confused here. I really love the power of c++ but it bends my logic.
What am I missing here?
You keep advancing tempo until it is equal to nullptr. At this point you have left the tree and all you have in hand is a pointer into nothingness. Note that in particular the program has no way of determining which node you last visited that led to tempo becoming null.
What you need to do instead is stop one step earlier: While tempo is still pointing to a node, but the next step would make it point to null. Now you still have a valid node of the tree in your hand and can attach the newly allocated node to it.
You can't save the pointer in tempo only. Tempo is a copy of your current position in the tree. You have to assign it to actual variable.
My solution to this problem would be to check if child is nullptr before you iterate
void SearchTree::insert(const int &x) {
if (!m_root) {
m_root = new Node(x);
return;
}
Node* tempo = m_root;
while (true) {
if (tempo->m_info >= x) {
if (!tempo->m_left) {
tempo->m_left = new Node(x);
return;
}
tempo = tempo->m_left;
} else {
if (!tempo->m_right) {
tempo->m_right = new Node(x);
return;
}
tempo = tempo->m_right;
}
}
}
Also you should use smart pointers instead of raw pointers.
An alternative solution is a pointer to pointer. I didn't test it but you can try
void SearchTree::insert(const int &x) {
Node** tempo = &m_root;
while (*tempo) {
if ((*tempo)->m_info >= x) {
tempo = &(*tempo)->m_left;
} else {
tempo = &(*tempo)->m_right;
}
}
*tempo = new Node(x);
}
In this image you can see. If you use Node* tempo = m_root then tempo contains a copy of the value in m_root. If you change tempo then m_root stays unchanged.
If you use Node** tempo = &m_root then tempo is pointer to m_root. You can change m_root through tempo.
I am currently working on a project to simulate Traffic Flow around a Roundabout and in order to do this I have built 2 data structures "LinearQueue" and "CircularQueue" both implemented using Linked List struct nodes.
My CircularQueue class has methods to enqueue and dequeue as is typical of any circular queue type structure, however as I have 4 (well 8 actually given roads going in both directions) LinearQueue objects that will need to link at quarter capacity intervals of the CircularQueue (roundabout) object I require a method to enqueue items at an offset from the rear or front of the queue and I am unsure of how to implement this properly.
Here is my CircularQueue::enqueue(Type) method:
Type enqueue(Type& item) {
// if the currentSize is greater than the maximum allowed capacity,
// throw a CircularQueueException
if (this->currentSize == this->maxCapacity) {
throw CircularQueueException("Circular queue is full, cannot enqueue any more objects!");
}
// if the front of this CQ object is null, assign first element of circularQueue array to
// front of queue and set the rear to the front (single-element queue)
if (this->front == 0) {
this->front = this->circularQueue[0];
this->front->head = item;
this->rear = this->front;
}
// else if the front is not-null, assign the tail of the rear of this CQ object
// to a new CQNode with head = item, and shift the new rear to tail of old rear
else {
this->rear->tail = new CQNode(item);
this->rear = this->rear->tail;
// if the currentSize of the queue is 1 less than the maximum capacity, then
// point to tail of the rear to the front of the queue
if (this->currentSize == (this->maxCapacity - 1))
this->rear->tail = this->front;
}
// increment the currentSize of this CircularQueue instance by 1 indicating enqueue successful
this->currentSize++;
return item;
}
where currentSize and maxCapacity are integer field variables storing the current filled queue size and maximum allowed capacity, respectively. Front and rear are pointers to the following node structure:
struct CQNode {
Type head;
CQNode* tail;
CQNode() {
//this->head = 0;
this->tail = 0;
}
CQNode(Type& head, CQNode* tail = 0) {
this->head = head;
this->tail = tail;
}
};
And Type is a typename given in the template of the class.
I currently only have the following for my offset enqueue method:
Type enqueue(Type& item, int offset) {
// if the offset given is 0, then simply call overloaded enqueue with just the item
if (offset == 0) {
return enqueue(item);
}
Type* itemPtr = &item;
if (itemPtr == 0) {
throw std::invalid_argument("Item to be enqueued onto Circular Queue cannot be null!");
}
if (this->currentSize == this->maxCapacity) {
throw CircularQueueException("Circular queue is full, cannot enqueue any more items.");
}
}
I'm just struggling to find where to start with the method, as I can see plenty of problems with null pointers by enqueuing and dequeuing objects at different offsets in my CircularQueue.
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);
}
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;
}
}