1
votes

I have implemented a queue using linked list. I added a enqueue and dequeue function. As per the data structure, if after using dequeue, the item after 'front' item should become front but my code is setting 3rd item on queue as front. Please look at my code and tell me what I did wrong.

class Node {
  constructor(value) {
    this.value = value;
    this.prev = null;
  }
}
class Queue {
  constructor() {
    this.front = null;
    this.rear = null;
    this.length = 0;
  }
  enqueue(value) {
    const newNode = new Node(value);
    if (this.length === 0) {
      this.front = newNode;
      this.rear = newNode;
    } else {
      this.front.prev = this.rear;
      this.rear = newNode;
    }
    this.length++;
    
    return newNode;
  }
  dequeue() {
    if (!this.front) {
      return null;
    }
    if (this.front === this.rear) {
      this.rear = null;
    } else {
      this.front = this.front.prev;
      this.length--;
    }
    return this.front;
  }
}

const myQueue = new Queue();

console.log('myQueue.enqueue(5) : ', myQueue.enqueue(5));
console.log('myQueue : ', myQueue);

console.log('myQueue.enqueue(6) : ', myQueue.enqueue(6));
console.log('myQueue : ', myQueue);

console.log('myQueue.enqueue(7) : ', myQueue.enqueue(7));
console.log('myQueue : ', myQueue);

console.log('myQueue.dequeue() : ', myQueue.dequeue());
console.log('myQueue : ', myQueue);

console.log('myQueue.dequeue() : ', myQueue.dequeue());
console.log('myQueue : ', myQueue);
.as-console-wrapper { max-height: 100%!important; top: 0; }
1
You have no "storage" every element that's put gets lost irrevocably after a subsequent enqueue !Vinay

1 Answers

0
votes

There are two answer parts ...

  1. the original first answer,
  2. and the second updated answer that deals with the OP's linked-list.

1st Answer

There was an incrementation bug this.length- instead of this.length--;.

And how about using a Queue approach that encapsulates a list structure like an Array?..

class Node {
  constructor(value) {
    this.value = value;
    this.prev = null;
  }
}

class Queue {
  constructor() {

    const queue = [];

    this.front = null;
    this.rear = null;
    this.length = queue.length;

    Object.defineProperty(this, 'enqueue', {
      value: function (value) {

        const node = new Node(value);
        const itemCount = queue.push(node);

        node.prev = queue[itemCount - 2] || null;

        this.front = queue[0];
        this.rear = queue[itemCount - 1];
        this.length = itemCount;

        return node;
      }
    });
    Object.defineProperty(this, 'dequeue', {
      value: function () {

        const node = queue.shift() || null;
        const itemCount = queue.length;

        this.front = queue[0] || null;
        this.rear = queue[itemCount - 1] || null;
        this.length = itemCount;

        return node;
      }
    });
  }
}

const queue = new Queue();

console.log('queue.enqueue(5) : ', queue.enqueue(5));
console.log('queue.enqueue(6) : ', queue.enqueue(6));
console.log('queue.enqueue(7) : ', queue.enqueue(7));

console.log('queue.dequeue() : ', queue.dequeue());
console.log('queue.dequeue() : ', queue.dequeue());

console.log(queue);
.as-console-wrapper { max-height: 100%!important; top: 0; }

2nd Iteration with Linked List Approach

A proper dequeuing process relies rather on properly maintained next links. The prev linking is just a nice to have feature on top ... proof of concept ...

class Node {
  constructor(value) {
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

class Queue {
  constructor() {
    this.front = null;
    this.rear = null;
    this.length = 0;
  }
  enqueue(value) {
    const enqueuedNode = new Node(value);

    if (this.rear !== null) {
      this.rear.next = enqueuedNode;
    }
    enqueuedNode.prev = this.rear;

    const itemCount = ++this.length;
    if (itemCount === 1) {

      this.front = enqueuedNode;
    }
    this.rear = enqueuedNode;

    return enqueuedNode;
  }
  dequeue() {
    const dequeuedNode = this.front;
    if (dequeuedNode !== null) {

      dequeuedNode.prev = null;
      // dequeuedNode.next = null;
    }
    this.front = dequeuedNode && dequeuedNode.next;

    const itemCount = --this.length;
    if (itemCount === 0) {

      this.rear = null;

    } else if (itemCount <= -1) {

      this.length = 0;
    }
    return dequeuedNode;
  }
}

const queue = new Queue();

console.log('queue.enqueue(5) : ', queue.enqueue(5));
console.log('queue : ', queue);

console.log('queue.enqueue(6) : ', queue.enqueue(6));
console.log('queue : ', queue);

console.log('queue.enqueue(7) : ', queue.enqueue(7));
console.log('queue : ', queue);

console.log('queue.dequeue() : ', queue.dequeue());
console.log('queue : ', queue);

console.log('queue.dequeue() : ', queue.dequeue());
console.log('queue : ', queue);
.as-console-wrapper { max-height: 100%!important; top: 0; }