先赞再看, 养成习惯 :P
俗话说得好, "时刻准备着"。前端
算法和数据结构, 对工程师来讲是十分重要的。 node
而这一部分, 靠短时间的冲刺学习是很难掌握的。只有靠刻意的学习和不断练习才能掌握。面试
今天咱们就来复习下队列。算法
队列是很是常见的数据结构, 面试中也常常出现。segmentfault
今天咱们就说一下这种数据结构, 而后看两道题。数组
文中可能涉及到链表,链表我在以前的文章中写过,参考连接:数据结构
[第28期] 回顾一下常见的链表操做
[第29期] 熟悉链表的几个经典题目数据结构和算法
队列是一种线性的数据结构, 表现上是先进先出, FIFO.函数
生活中典型的场景就是排队了,从后插入新元素, 移除最旧的元素:学习
下面咱们用两种姿式来实现一个队列:
使用栈实现队列的下列操做:
示例:
MyQueue queue = new MyQueue(); queue.push(1); queue.push(2); queue.peek(); // 返回 1 queue.pop(); // 返回 1 queue.empty(); // 返回 false
栈是一种先进后出的数据结构, 队列是一种先进先出的数据结构,那怎么用栈来模拟队列呢?
很简单, 倒两次就好了。
用两个栈, 一个用于入队, 一个用于出队:
图解:
代码实现:
/** * Initialize your data structure here. */ var MyQueue = function() { this.input = []; this.output = []; }; /** * Push element x to the back of queue. * @param {number} x * @return {void} */ MyQueue.prototype.push = function(x) { this.input.push(x); }; /** * Removes the element from in front of queue and returns that element. * @return {number} 从队列首部移除元素 */ MyQueue.prototype.pop = function() { while (this.input.length) { this.output.push(this.input.pop()); } var first = this.output.pop(); while (this.output.length) { this.input.push(this.output.pop()); } return first; }; /** * Get the front element. 返回队列首部的元素。 * @return {number} */ MyQueue.prototype.peek = function() { return this.input[0]; }; /** * Returns whether the queue is empty. * @return {boolean} 返回队列是否为空 */ MyQueue.prototype.empty = function() { return !this.input.length && !this.output.length; }; var obj = new MyQueue(); obj.push(1); obj.push(2); obj.push(3); var param_2 = obj.pop(); console.log(param_2); // 队首出来, 1 var param_3 = obj.peek(); console.log(param_3); // 返回队列首部的元素: 2 var param_4 = obj.empty(); console.log('isEmpty: ', param_4); // false
链表咱们都很熟悉了, 以前两期都是关于链表的:xxx, xxx
先看一下基础结构, 包含咱们要实现哪些功能:
// Queue using linkedlist function QueueUsingLinkList() { let Node = function(elm) { this.element = elm; this.next = null; }; // To keep track of the size let length = 0; //To keep track of the list let head = null; // Enqueue data in the queue this.enqueue = function(elm) {}; // Remove the item from the queue this.dequeue = function() {}; // Return the first element in the queue this.peek = function() {}; //Return the last element in the queue this.rear = function() {}; //Check if queue is empty this.isEmpty = function() {}; //Return the size of the queue this.size = function() {}; //Clear the queue this.clear = function() {}; }
首先要检查队列是否是空的, 若是是空的, 就把新元素当成头结点,不然, 就把新元素加到末尾。
代码实现:
//Enqueue data in the queue this.enqueue = function (elm) { let node = new Node(elm), current; //If head is empty then //Add the node at the beginning if (head === null) { head = node; } else { //Else add the node as the //Next element of the existing list current = head; while (current.next) { current = current.next; } current.next = node; } //Increase the length length++; };
队列是先进先出的数据结构, 因此出队的时候, 要移除并返回头部的元素,长度减一,并把指针日后移步一位。
代码实现:
//Remove the item from the queue this.dequeue = function () { let current = head; //If there is item then remove it //and make the next element as the first if (current) { let elm = current.element; current = current.next; head = current; length--; return elm; } return null; }
核心的入队, 出队,咱们已经实现了, 为了方便调试, 咱们顺便实现几个辅助函数:
//Check if queue is empty this.isEmpty = function() { return length === 0; }
//Return the size of the queue this.size = function() { return length; }
//Convert the queue to an array this.toArray = function () { let arr = []; let current = head; while (current) { arr.push(current.element); current = current.next; } return arr; }
//Return the last element in the queue this.rear = function () { let current = head; //If head is empty //Return null if (current === null) { return null; } //Return the last elememnt while (current.next) { current = current.next; } return current.element; }
//Return the first element in the queue this.peek = function () { if (head) { return head.element; } return null; }
//Clear the queue this.clear = function() { head = null; length = 0; }
let queue = new QueueUsingLinkList(); console.log(queue.isEmpty()); // true queue.enqueue('pranav'); queue.enqueue('sachin'); queue.enqueue('yogesh'); console.log(queue.toArray()); // ["pranav", "sachin", "yogesh"] queue.dequeue(); queue.dequeue(); console.log(queue.toArray()); // ["yogesh"] queue.enqueue('prashant'); queue.enqueue('yadav'); queue.dequeue(); console.log(queue.toArray()); // ["prashant", "yadav"] console.log(queue.size()); // 2 console.log(queue.peek()); // "prashant" console.log(queue.rear()); // "yadav"
//Queue using linkedlist function QueueUsingLinkList() { //Node let Node = function (elm) { this.element = elm; this.next = null; } //To keep track of the size let length = 0; //To keep track of the list let head = null; //Enqueue data in the queue this.enqueue = function (elm) { let node = new Node(elm), current; //If head is empty then //Add the node at the beginning if (head === null) { head = node; } else { //Else add the node as the //Next element of the existing list current = head; while (current.next) { current = current.next; } current.next = node; } //Increase the length length++; } //Remove the item from the queue this.dequeue = function () { let current = head; //If there is item then remove it //and make the next element as the first if (current) { let elm = current.element; current = current.next; head = current; length--; return elm; } return null; } //Return the first element in the queue this.peek = function () { if (head) { return head.element; } return null; } //Return the last element in the queue this.rear = function () { let current = head; //If head is empty //Return null if (current === null) { return null; } //Return the last elememnt while (current.next) { current = current.next; } return current.element; } //Convert the queue to an array this.toArray = function () { let arr = []; let current = head; while (current) { arr.push(current.element); current = current.next; } return arr; } //Check if queue is empty this.isEmpty = function () { return length === 0; } //Return the size of the queue this.size = function () { return length; } //Clear the queue this.clear = function () { head = null; length = 0; } }
掌握这些常见的数据结的基础操做,对咱们的平常工做也有好处。
要学好数据结构和算法, 须要 三分理论, 七分实践。
但愿今天的内容对你有所启发,谢谢 :)
若是你以为内容有帮助, 能够关注下个人公众号 「 前端e进阶 」,一块儿学习, :)