123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- // Copyright 2006 The Closure Library Authors. All Rights Reserved.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS-IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- /**
- * @fileoverview Datastructure: Queue.
- *
- *
- * This file provides the implementation of a FIFO Queue structure.
- * API is similar to that of com.google.common.collect.IntQueue
- *
- * The implementation is a classic 2-stack queue.
- * There's a "front" stack and a "back" stack.
- * Items are pushed onto "back" and popped from "front".
- * When "front" is empty, we replace "front" with reverse(back).
- *
- * Example:
- * front back op
- * [] [] enqueue 1
- * [] [1] enqueue 2
- * [] [1,2] enqueue 3
- * [] [1,2,3] dequeue -> ...
- * [3,2,1] [] ... -> 1
- * [3,2] [] enqueue 4
- * [3,2] [4] dequeue -> 2
- * [3] [4]
- *
- * Front and back are simple javascript arrays. We rely on
- * Array.push and Array.pop being O(1) amortized.
- *
- * Note: In V8, queues, up to a certain size, can be implemented
- * just fine using Array.push and Array.shift, but other JavaScript
- * engines do not have the optimization of Array.shift.
- *
- */
- goog.provide('goog.structs.Queue');
- goog.require('goog.array');
- /**
- * Class for FIFO Queue data structure.
- *
- * @constructor
- * @template T
- */
- goog.structs.Queue = function() {
- /**
- * @private {!Array<T>} Front stack. Items are pop()'ed from here.
- */
- this.front_ = [];
- /**
- * @private {!Array<T>} Back stack. Items are push()'ed here.
- */
- this.back_ = [];
- };
- /**
- * Flips the back stack onto the front stack if front is empty,
- * to prepare for peek() or dequeue().
- *
- * @private
- */
- goog.structs.Queue.prototype.maybeFlip_ = function() {
- if (goog.array.isEmpty(this.front_)) {
- this.front_ = this.back_;
- this.front_.reverse();
- this.back_ = [];
- }
- };
- /**
- * Puts the specified element on this queue.
- * @param {T} element The element to be added to the queue.
- */
- goog.structs.Queue.prototype.enqueue = function(element) {
- this.back_.push(element);
- };
- /**
- * Retrieves and removes the head of this queue.
- * @return {T} The element at the head of this queue. Returns undefined if the
- * queue is empty.
- */
- goog.structs.Queue.prototype.dequeue = function() {
- this.maybeFlip_();
- return this.front_.pop();
- };
- /**
- * Retrieves but does not remove the head of this queue.
- * @return {T} The element at the head of this queue. Returns undefined if the
- * queue is empty.
- */
- goog.structs.Queue.prototype.peek = function() {
- this.maybeFlip_();
- return goog.array.peek(this.front_);
- };
- /**
- * Returns the number of elements in this queue.
- * @return {number} The number of elements in this queue.
- */
- goog.structs.Queue.prototype.getCount = function() {
- return this.front_.length + this.back_.length;
- };
- /**
- * Returns true if this queue contains no elements.
- * @return {boolean} true if this queue contains no elements.
- */
- goog.structs.Queue.prototype.isEmpty = function() {
- return goog.array.isEmpty(this.front_) && goog.array.isEmpty(this.back_);
- };
- /**
- * Removes all elements from the queue.
- */
- goog.structs.Queue.prototype.clear = function() {
- this.front_ = [];
- this.back_ = [];
- };
- /**
- * Returns true if the given value is in the queue.
- * @param {T} obj The value to look for.
- * @return {boolean} Whether the object is in the queue.
- */
- goog.structs.Queue.prototype.contains = function(obj) {
- return goog.array.contains(this.front_, obj) ||
- goog.array.contains(this.back_, obj);
- };
- /**
- * Removes the first occurrence of a particular value from the queue.
- * @param {T} obj Object to remove.
- * @return {boolean} True if an element was removed.
- */
- goog.structs.Queue.prototype.remove = function(obj) {
- return goog.array.removeLast(this.front_, obj) ||
- goog.array.remove(this.back_, obj);
- };
- /**
- * Returns all the values in the queue.
- * @return {!Array<T>} An array of the values in the queue.
- */
- goog.structs.Queue.prototype.getValues = function() {
- var res = [];
- // Add the front array in reverse, then the back array.
- for (var i = this.front_.length - 1; i >= 0; --i) {
- res.push(this.front_[i]);
- }
- var len = this.back_.length;
- for (var i = 0; i < len; ++i) {
- res.push(this.back_[i]);
- }
- return res;
- };
|