Using js to implement those data structures 06 (queues)

Keywords: REST

In fact, there are many similarities between queues and stacks, including some of the methods and ways of using them. Only queues use a completely different principle from stacks. Stacks use the last in first out principle, while queues use the First In First Out principle.

I. queue

     queue It is a special linear table. The special thing is that it only allows deletion at the front of the table and insertion at the rear of the table. Like stack, queue is a linear table with limited operation. The end of the insertion operation is called the end of the queue, and the end of the deletion operation is called the head of the queue. When there are no elements in the queue, it is called an empty queue.
The data elements of a queue are also called queue elements. Inserting a queue element into a queue is called queuing, and deleting a queue element from a queue is called queuing. Because queues can only be inserted at one end and deleted at the other end, only the elements that enter the queue first can be deleted from the queue first. Therefore, queues are also called FIFO first in first out linear tables.
We have a basic understanding of queues, so let's see how to implement queues. In fact, it is very similar to the implementation of stack, but the methods of entering and leaving the queue are slightly different. Let's see what methods are needed for a complete queue:
1. enqueue(element(s)), enter the queue, and add one or more elements to the end of the queue.
2. dequeue(), get out of the queue, remove the first element in the queue, that is, the first element in the queue, and return the element.
3. front(), get the first element of the queue, and return the first element in the queue (the element that is added first and removed first). The queue does not remove the element.
4. isEmpty() to determine whether the queue does not contain any elements.
5. size() returns the total number of elements in the queue.
 //Declare Queue class
  function Queue() {
      //Declare and initialize an array to hold queue elements.
      let items = [];
      //Add queue element
      this.enqueue = function (element) {
          items.push(element)
      };
      //Remove and return the queue element
      this.dequeue = function () {
          return items.shift();
      };
      //Get queue header element
      this.front = function () {
          return items[0];
      };
      //Judge whether the queue element is empty
      this.isEmpty = function () {
          return items.length == 0;
      };

      //Get the number of queue elements
      this.size = function () {
          return items.length;
      };
      //Print the queue
      this.print = function () {
          console.log(items.toString())
      };
  }
const queue = new Queue();
console.log(queue.isEmpty()); // outputs true
queue.enqueue('John');
queue.enqueue('Jack');
queue.print(); // John,Jack
queue.enqueue('Camila');
queue.print(); // John,Jack,Camila
console.log(queue.size()); // outputs 3
console.log(queue.isEmpty()); // outputs false
queue.dequeue(); // remove John
queue.dequeue(); // remove Jack
queue.print(); // Camila

We have already implemented the data structure of queue. In the same way, can we change it a little to make the implementation of queue look more beautiful?

let Queue = (function () {
      const items = new WeakMap();

      class Queue {
          constructor () {
        //It is important to note that items here are data of type WeakMap, while WeakMap is a key value pair. There are exclusive set and get methods to get and set values.
        //So [] is set here for this, i.e. this is the key name and [] is the value, so the queue formed by this method is still an operation on the array. items.set(this,[]); } enqueue(element) { let q = items.get(this);//The q here is the same as the [] q.push(element); } dequeue() { let q = items.get(this); let r = q.shift(); return r; } front() { return items.get(this)[0]; } isEmpty() { return items.get(this).length == 0; } size() { return items.get(this).length; } print() { console.log(items.get(this)); } } return Queue; })()

In fact, the introduction of the queue is basically finished here, but I feel that it's a little tricky. So let's finish the rest in this article.

2. Priority queue
We're done with queues, so let's see what priority queues are. A normal queue is a first in, first out data structure in which elements are appended at the end of the queue and removed from the queue head. In the priority queue, elements are given priority. When accessing an element, the element with the highest priority is deleted first. Priority queues have the behavior characteristics of first in, largest out. It's like we buy tickets at the window and line up at the airport. Normally, we enter from the front of the queue according to the order of the queue, but there is a rule that the elderly, children and soldiers have priority, so we give the elderly (children and soldiers) the right to jump in the queue. Priority queue, in turn, gives a specific element the right to queue (priority). I want to join the team, not necessarily directly to the end. Instead, I insert the queue based on the priority I set.
In fact, the difference in the implementation of priority queues is the setting of queue elements and the method of queue entry (there are actually two ways to achieve this, one is by priority, the other is by priority, here we only use the first way to achieve this). Let's see how to implement priority queues.
  //Declare Queue class
  function PriorityQueue() {
      //Declare and initialize an array to hold queue elements.
      let items = [];
      //Create an element class with priority
      function QueueElement(element,priority) {
          this.element = element;
          this.priority = priority;
      }
      //Add queue element
      this.enqueue = function (element,priority) {
          let queueElement = new QueueElement(element,priority);
          let added = false;
          //Traverse the queue element, 1 has the highest priority, and so on. If the priority of the current element is greater than items[i], put the element in front of items[i].
          //If the second parameter of the splice method is 0, the third parameter is added before i.
          for(let i = 0; i < items.length; i  ) {
              if(queueElement.priority < items[i].priority) {
                  items.splice(i,0,queueElement);
                  added = true;break;
              }
          }
          // Determine whether the element can be listed directly through added.
          if(!added) {
              items.push(queueElement);
          }
      };
      //Remove and return the queue element
      this.dequeue = function () {
          return items.shift();
      };
      //Get queue header element
      this.front = function () {
          return items[0];
      };
      //Judge whether the queue element is empty
      this.isEmpty = function () {
          return items.length == 0;
      };

      //Get the number of queue elements
      this.size = function () {
          return items.length;
      };
      //Circular print element and its priority "`" are template strings of ES6
      this.print = function () {
          for(let i = 0; i < items.length; i  ) {
              console.log(`${items[i].element} - ${items[i].priority}`);
          }
      };
  }
const queue = new PriorityQueue();
console.log(queue.isEmpty()); // outputs true

queue.enqueue('zaking',2);
queue.enqueue('linbo',6);
queue.enqueue('queue',5);
queue.enqueue('ada',3);
queue.enqueue('John',1);
queue.enqueue('Jack',2);
queue.enqueue('Camila',3);
queue.enqueue('zak',3);
queue.print(); 

The main change lies in the setting of queue elements and enqueue method. Since priority needs to be set for each cyclic queue element, the queue element is slightly changed to have two parameters (element itself and priority). Since the queue is inserted according to different priority, the enqueue method of cyclic queue also needs to be cyclic. The entire queue to determine where to insert.

In fact, the implementation of this priority queue is not very good. For example, if I do not transfer the second priority parameter, the parameter is undefined when the queue is printed, and it should be the last priority by default when the parameter is not transferred. You can try to modify the code to make it look more realistic.
 
III. circular queue
In addition to the priority queue, there is also a circular queue. An easy to imagine example of the circular queue is the drum game. The rules of the game don't say that everyone played it as a child. Let's see how to realize the drum game.
function hotPotato(nameList, num) {
  const queue = new Queue();
  //Put all the names in order
  for (let i = 0; i < nameList.length; i  ) {
    queue.enqueue(nameList[i]);
  }

  //Declare the name of the currently eliminated personnel
  let eliminated = '';
  //If there is more than one element in the queue, there is no final winner. If there is only one element left, the last winner will be listed.
  while (queue.size() > 1) {
      //Loop the current queue num times, and re-enter the "dequeue element" in the queue header.
    for (let i = 0; i < num; i  ) {
      queue.enqueue(queue.dequeue());
    }
    //At the end of the loop, the elements of the current queue are listed, which is the knockout.
    eliminated = queue.dequeue();
    queue.print();
    console.log(eliminated   "Be eliminated");
  }

  return queue.dequeue();
}

let names = ["zak","zaking","james","lili","bole","londo","fali"]
console.log(hotPotato(names,7))

In the above method, each cycle will successively put the head element into the tail, and then a cycle is realized. After the cycle, the element at the front end of the queue is regarded as eliminated, until only one element is left at the end, which is a real simulation of the drum game.

 

Finally, due to my limited level, my ability is still far from that of the great God. If there is any mistake or ambiguity, I hope you will give me some advice. Thank you very much.


For more professional front-end knowledge, please go to [ape 2048] www.mk2048.com

Posted by Jason28 on Thu, 24 Oct 2019 00:00:59 -0700