I am starting to jump into C++ right now for my class, and we covered enqueue and dequeue in Scheme. However, we're doing it in C++ now, and we need to use pointers, which I am struggling to understand. I understand what pointers are, when to use them, etc. However, I'm struggling to figure out how to implement them into this lab. I currently have this for code:
#include <stdlib.h>
#include <iostream>
#include <assert.h>
using namespace std;
struct node {
int item;
node* next;
};
typedef node* nodePtr;
typedef nodePtr* queue;
queue makeQueue() {
queue q = new nodePtr[2];
q[0] = NULL;
q[1] = NULL;
return q;
}
nodePtr start(queue q) {
return q[0];
}
nodePtr tail(queue q) {
return q[1];
}
void setStart(queue q, nodePtr newNode) {
q[0] = newNode;
}
void setTail(queue q, nodePtr newNode) {
q[1] = newNode;
}
bool emptyQueue(queue q) {
return q[0] == NULL;
}
int head(queue q) {
if (emptyQueue(q)) {
cout << "Attempt to take head of an empty queue.\n";
exit(1);
}
return start(q)->item;
}
void enqueue(queue q, int newItem) {
// Answer goes here.
}
void dequeue(queue q) {
// Answer goes here.
}
For this code, I understand what I need to do: Enqueue will push newItem onto the cdr (or tail) of the queue, and Dequeue will remove the node at the start of the queue, with appropriate locations updated accordingly. But it's just the pointers that are really confusing me, and I don't know what to do.
How would I dive into writing enqueue and dequeue with pointers? I'm going to blankly assume that enqueue and dequeue shouldn't be lines and lines of code.
Thank you so much!
When dealing with pointer based dynamic structures like stack, linked lists and queues, it is all about rearranging pointers. As it has been suggested in the comments, representing pointers as arrows on paper pointing to nodes will help visualise how you need to reassign pointer when en-/dequeuing.
I would also like to point out that you shouldn't mix C and C++ headers as you did. The C++ library includes the same definitions as the C language library organized in the same structure of header files. Each header file has the same name as the C language version but with a "c" prefix and no extension. For example, the C++ equivalent for the C language header file <stdlib.h>
is <cstdlib>
, similarly, <assert.h>
is <cassert>
. Furthermore, in C++, the NULL pointer is nullptr
; mixing NULL
and nullptr
may cause you problems when overloading functions with int
and pointer arguments.
Now to the problem at hand. Each node
has a member next
, which is an arrow pointing to the next node
in the queue. It seems, q[0]
and q[1]
are the respective arrows to the first and last element.
If you want to enqueue a new element from the payload data only (not the full node
) then you will have to dynamically create the node
object first. Then its next
pointer has to point to what q[0]->next
is pointing to while q[0]->next
has to be reassigned to point to the new node you just created:
Before:
q[0]->next ---> somenode
After:
q[0]->next -. -XXX-> somenode
| ^
| |
'-> newnode->next -'
Or in C++ (without validation):
void enqueue(queue q, int newItem) {
nodePtr newnode = new node;
newnode->item = newItem;
newnode->next = q[0]->next;
q[0]->next = newnode;
}
Dequeuing goes accordingly, just look how you need to rearrange the pointers. Don't forget to delete
removed nodes and also provide a function to delete the queue
that makeQueue
creates.