先贊再看, 養成習慣 :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進階 」,一塊兒學習, :)