0

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!

  • 2
    It is unclear what is the question. – Vlad from Moscow Nov 29 '19 at 17:39
  • 1
    Draw a sketch of the `node` object and their subobjects and draw arrows showing to which `node` instance all the `node` pointers point. Make this graph for how it looks before you `enqueue` a new node and after. Then try to implement the necessary changes of the `next` pointers. If you have a concrete problem with this, then please ask specifically. – walnut Nov 29 '19 at 17:43

1 Answers1

0

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 makeQueuecreates.

  • Worked for me. However, I had to tweak enqueue a little. I replaced "newnode->next = q[0]->next;" with "newNode->next = NULL;", then created an if/else statement to check if the queue was empty or not. –  Nov 29 '19 at 21:03