In fact, there are many similarities between queues and stacks, including some of their methods and usage, but the queue uses a completely different principle from the stack. The stack is the last-in, first-out principle, while the queue is First In First Out.
1. Queue
// Declare the Queue class function Queue() { // Declare and initialize an array for storing 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 the queue head element this .front = function () { return items[0 ]; }; // Determine 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 the queue above. Similarly, can we make a little modification to make the implementation of the queue look more beautiful.
let Queue = (function () { const items = new WeakMap(); class Queue { constructor () {
//For emphasis, items here are WeakMap type data, and WeakMap is a key-value pair, with its own set and get methods to get and set the value,
//So here [] is set for this, that is, with 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 equivalent to [] 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 queue has basically been introduced here, but it feels a bit confusing. So let's finish the rest of the content in this article.
// Declare Queue class function PriorityQueue() { // Declare and initialize an array to store 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 elements, 1 has the highest priority, and so on, if the current element's priority is greater than items[i], then put the element in front of items[i]. // If the second parameter of the splice method is 0, then add the third parameter to the front of 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 directly added to the column by added. if (! added) { items.push(queueElement); } }; // Remove and return the queue element this .dequeue = function () { return items.shift(); }; // Get the queue head element this .front = function () { return items[0 ]; }; // Determine 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; }; // loop to print elements and their priority "``" is an ES6 template string 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 the enqueue method. Since the priority needs to be set for each element of the circular queue, the elements of the queue are slightly changed here to have two parameters (the element itself and the priority), Then since the queue needs to be inserted according to different priorities, the enqueue method of the circular queue also needs to loop the entire queue to determine where to insert.
function hotPotato(nameList, num) { const queue = new Queue(); // List all the lists (nameList) in sequence 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, it means there is no final winner, if there is only one left, dequeue the final winner while (queue.size( ) > 1 ) { // Loop the current queue num times, and re-enter the "dequeue element" at the head of the queue. for (let i = 0; i < num; i++ ) { queue.enqueue(queue.dequeue()); } // After the loop ends, dequeue the elements of the current queue, that is, the knockout. eliminated = queue.dequeue(); queue.print(); console.log(eliminated + "eliminated" ); } return queue.dequeue(); } let names = ["zak","zaking","james","lili","bole","londo","fali"] console.log(hotPotato(names,7))
In the above method, each loop will put the head element into the tail in turn, which realizes a circle, and then after the loop ends, the element at the front of the queue is regarded as eliminated, until there is only one element left at the end, that is, A real simulation of the drumming game.
Finally, due to my limited level, my ability is still far from that of the Great God. If there are mistakes or unclear points, I hope everyone will give me some advice and corrections. thank you very much!