Quel est le meilleur moyen d'implémenter une pile et une file d'attente en JavaScript?
Je cherche à utiliser l'algorithme de parc de triage et j'aurai besoin de ces structures de données.
var stack = [];
stack.Push(2); // stack is now [2]
stack.Push(5); // stack is now [2, 5]
var i = stack.pop(); // stack is now [2]
alert(i); // displays 5
var queue = [];
queue.Push(2); // queue is now [2]
queue.Push(5); // queue is now [2, 5]
var i = queue.shift(); // queue is now [5]
alert(i); // displays 2
extrait de " 9 astuces javascript que vous ignorez peut-être "
Javascript a des méthodes push et pop, qui fonctionnent sur des objets de tableau Javascript ordinaires.
Pour les files d'attente, regardez ici:
http://safalra.com/web-design/javascript/queues/
Les files d'attente peuvent être implémentées dans JavaScript en utilisant soit le Push et le méthodes shift ou unshift et pop méthodes de l'objet tableau. Bien que c'est un moyen simple d'implémenter files d'attente, il est très inefficace pour grandes files d'attente - parce que les méthodes opérer sur des tableaux, le passage et les méthodes unshift déplacent chaque élément dans le tableau à chaque fois qu'ils sont appelés.
Queue.js est une implémentation de file d'attente simple et efficace pour JavaScript dont la fonction de retrait de file d'attente s'exécute en temps constant amorti. Par conséquent, pour les files d'attente plus volumineuses, il peut être nettement plus rapide que d'utiliser des tableaux.
Tableaux.
Empiler:
var stack = [];
//put value on top of stack
stack.Push(1);
//remove value from top of stack
var value = stack.pop();
Queue:
var queue = [];
//put value on end of queue
queue.Push(1);
//Take first value from queue
var value = queue.shift();
Si vous voulez créer vos propres structures de données, vous pouvez créer les vôtres:
var Stack = function(){
this.top = null;
this.size = 0;
};
var Node = function(data){
this.data = data;
this.previous = null;
};
Stack.prototype.Push = function(data) {
var node = new Node(data);
node.previous = this.top;
this.top = node;
this.size += 1;
return this.top;
};
Stack.prototype.pop = function() {
temp = this.top;
this.top = this.top.previous;
this.size -= 1;
return temp;
};
Et pour faire la queue:
var Queue = function() {
this.first = null;
this.size = 0;
};
var Node = function(data) {
this.data = data;
this.next = null;
};
Queue.prototype.enqueue = function(data) {
var node = new Node(data);
if (!this.first){
this.first = node;
} else {
n = this.first;
while (n.next) {
n = n.next;
}
n.next = node;
}
this.size += 1;
return node;
};
Queue.prototype.dequeue = function() {
temp = this.first;
this.first = this.first.next;
this.size -= 1;
return temp;
};
Ma mise en place de Stack et Queue en utilisant Linked List
// Linked List
function Node(data) {
this.data = data;
this.next = null;
}
// Stack implemented using LinkedList
function Stack() {
this.top = null;
}
Stack.prototype.Push = function(data) {
var newNode = new Node(data);
newNode.next = this.top; //Special attention
this.top = newNode;
}
Stack.prototype.pop = function() {
if (this.top !== null) {
var topItem = this.top.data;
this.top = this.top.next;
return topItem;
}
return null;
}
Stack.prototype.print = function() {
var curr = this.top;
while (curr) {
console.log(curr.data);
curr = curr.next;
}
}
// var stack = new Stack();
// stack.Push(3);
// stack.Push(5);
// stack.Push(7);
// stack.print();
// Queue implemented using LinkedList
function Queue() {
this.head = null;
this.tail = null;
}
Queue.prototype.enqueue = function(data) {
var newNode = new Node(data);
if (this.head === null) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
}
Queue.prototype.dequeue = function() {
var newNode;
if (this.head !== null) {
newNode = this.head.data;
this.head = this.head.next;
}
return newNode;
}
Queue.prototype.print = function() {
var curr = this.head;
while (curr) {
console.log(curr.data);
curr = curr.next;
}
}
var queue = new Queue();
queue.enqueue(3);
queue.enqueue(5);
queue.enqueue(7);
queue.print();
queue.dequeue();
queue.dequeue();
queue.print();
Vous pouvez implémenter des piles et des files d'attente en Javascript de plusieurs manières. La plupart des réponses ci-dessus sont des implémentations assez superficielles et je voudrais essayer d'implémenter quelque chose de plus lisible (en utilisant les nouvelles fonctionnalités de syntaxe de es6) et robuste.
Voici l'implémentation de la pile:
class Stack {
constructor(...items){
this._items = []
if(items.length>0)
items.forEach(item => this._items.Push(item) )
}
Push(...items){
//Push item to the stack
items.forEach(item => this._items.Push(item) )
return this._items;
}
pop(count=0){
//pull out the topmost item (last item) from stack
if(count===0)
return this._items.pop()
else
return this._items.splice( -count, count )
}
peek(){
// see what's the last item in stack
return this._items[this._items.length-1]
}
size(){
//no. of items in stack
return this._items.length
}
isEmpty(){
// return whether the stack is empty or not
return this._items.length==0
}
toArray(){
return this._items;
}
}
Et voici comment vous pouvez utiliser la pile:
let my_stack = new Stack(1,24,4);
// [1, 24, 4]
my_stack.Push(23)
//[1, 24, 4, 23]
my_stack.Push(1,2,342);
//[1, 24, 4, 23, 1, 2, 342]
my_stack.pop();
//[1, 24, 4, 23, 1, 2]
my_stack.pop(3)
//[1, 24, 4]
my_stack.isEmpty()
// false
my_stack.size();
//3
Si vous souhaitez voir une description détaillée de cette implémentation et de ses améliorations, vous pouvez lire ici: http://jschap.com/data-structures-in-javascript-stack/
Voici le code pour l'implémentation de la file d'attente dans es6:
class Queue{
constructor(...items){
//initialize the items in queue
this._items = []
// enqueuing the items passed to the constructor
this.enqueue(...items)
}
enqueue(...items){
//Push items into the queue
items.forEach( item => this._items.Push(item) )
return this._items;
}
dequeue(count=1){
//pull out the first item from the queue
this._items.splice(0,count);
return this._items;
}
peek(){
//peek at the first item from the queue
return this._items[0]
}
size(){
//get the length of queue
return this._items.length
}
isEmpty(){
//find whether the queue is empty or no
return this._items.length===0
}
}
Voici comment utiliser cette implémentation:
let my_queue = new Queue(1,24,4);
// [1, 24, 4]
my_queue.enqueue(23)
//[1, 24, 4, 23]
my_queue.enqueue(1,2,342);
//[1, 24, 4, 23, 1, 2, 342]
my_queue.dequeue();
//[24, 4, 23, 1, 2, 342]
my_queue.dequeue(3)
//[1, 2, 342]
my_queue.isEmpty()
// false
my_queue.size();
//3
Pour suivre l'intégralité du didacticiel sur la mise en œuvre de ces structures de données et sur l'amélioration de celles-ci, consultez la série "Jouer avec des structures de données en javascript" sur jschap.com. Voici les liens pour les files d'attente - http://jschap.com/playing-data-structures-javascript-queues/
/*------------------------------------------------------------------
Defining Stack Operations using Closures in Javascript, privacy and
state of stack operations are maintained
@author:Arijt Basu
Log: Sun Dec 27, 2015, 3:25PM
-------------------------------------------------------------------
*/
var stackControl = true;
var stack = (function(array) {
array = [];
//--Define the max size of the stack
var MAX_SIZE = 5;
function isEmpty() {
if (array.length < 1) console.log("Stack is empty");
};
isEmpty();
return {
Push: function(ele) {
if (array.length < MAX_SIZE) {
array.Push(ele)
return array;
} else {
console.log("Stack Overflow")
}
},
pop: function() {
if (array.length > 1) {
array.pop();
return array;
} else {
console.log("Stack Underflow");
}
}
}
})()
// var list = 5;
// console.log(stack(list))
if (stackControl) {
console.log(stack.pop());
console.log(stack.Push(3));
console.log(stack.Push(2));
console.log(stack.pop());
console.log(stack.Push(1));
console.log(stack.pop());
console.log(stack.Push(38));
console.log(stack.Push(22));
console.log(stack.pop());
console.log(stack.pop());
console.log(stack.Push(6));
console.log(stack.pop());
}
//End of STACK Logic
/* Defining Queue operations*/
var queue = (function(array) {
array = [];
var reversearray;
//--Define the max size of the stack
var MAX_SIZE = 5;
function isEmpty() {
if (array.length < 1) console.log("Queue is empty");
};
isEmpty();
return {
insert: function(ele) {
if (array.length < MAX_SIZE) {
array.Push(ele)
reversearray = array.reverse();
return reversearray;
} else {
console.log("Queue Overflow")
}
},
delete: function() {
if (array.length > 1) {
//reversearray = array.reverse();
array.pop();
return array;
} else {
console.log("Queue Underflow");
}
}
}
})()
console.log(queue.insert(5))
console.log(queue.insert(3))
console.log(queue.delete(3))
Le changement de tableau Javascript () est lent, en particulier lorsque de nombreux éléments sont conservés. Je connais deux façons d'implémenter une file d'attente avec une complexité O(1) amortie.
La première consiste à utiliser un tampon circulaire et un doublage de table. J'ai déjà implémenté cela auparavant. Vous pouvez voir mon code source ici https://github.com/kevyuu/rapid-queue
La deuxième façon consiste à utiliser deux piles. C'est le code pour la file d'attente avec deux piles
function createDoubleStackQueue() {
var that = {};
var pushContainer = [];
var popContainer = [];
function moveElementToPopContainer() {
while (pushContainer.length !==0 ) {
var element = pushContainer.pop();
popContainer.Push(element);
}
}
that.Push = function(element) {
pushContainer.Push(element);
};
that.shift = function() {
if (popContainer.length === 0) {
moveElementToPopContainer();
}
if (popContainer.length === 0) {
return null;
} else {
return popContainer.pop();
}
};
that.front = function() {
if (popContainer.length === 0) {
moveElementToPopContainer();
}
if (popContainer.length === 0) {
return null;
}
return popContainer[popContainer.length - 1];
};
that.length = function() {
return pushContainer.length + popContainer.length;
};
that.isEmpty = function() {
return (pushContainer.length + popContainer.length) === 0;
};
return that;}
Ceci est une comparaison de performance utilisant jsPerf
CircularQueue.shift () vs Array.shift ()
http://jsperf.com/rapidqueue-shift-vs-array-shift
Comme vous pouvez le constater, le jeu de données volumineux est nettement plus rapide
Voici une implémentation de file d'attente assez simple avec deux objectifs:
L'implémentation de la pile ne partage que le deuxième objectif.
// Queue
function Queue() {
this.q = new Array(5);
this.first = 0;
this.size = 0;
}
Queue.prototype.enqueue = function(a) {
var other;
if (this.size == this.q.length) {
other = new Array(this.size*2);
for (var i = 0; i < this.size; i++) {
other[i] = this.q[(this.first+i)%this.size];
}
this.first = 0;
this.q = other;
}
this.q[(this.first+this.size)%this.q.length] = a;
this.size++;
};
Queue.prototype.dequeue = function() {
if (this.size == 0) return undefined;
this.size--;
var ret = this.q[this.first];
this.first = (this.first+1)%this.q.length;
return ret;
};
Queue.prototype.peek = function() { return this.size > 0 ? this.q[this.first] : undefined; };
Queue.prototype.isEmpty = function() { return this.size == 0; };
// Stack
function Stack() {
this.s = new Array(5);
this.size = 0;
}
Stack.prototype.Push = function(a) {
var other;
if (this.size == this.s.length) {
other = new Array(this.s.length*2);
for (var i = 0; i < this.s.length; i++) other[i] = this.s[i];
this.s = other;
}
this.s[this.size++] = a;
};
Stack.prototype.pop = function() {
if (this.size == 0) return undefined;
return this.s[--this.size];
};
Stack.prototype.peek = function() { return this.size > 0 ? this.s[this.size-1] : undefined; };
Sinon, vous pouvez utiliser deux baies pour implémenter la structure de données en file d'attente.
var temp_stack = new Array();
var stack = new Array();
temp_stack.Push(1);
temp_stack.Push(2);
temp_stack.Push(3);
Si je dépose les éléments maintenant, la sortie sera 3,2,1 . Mais nous voulons une structure FIFO afin que vous puissiez faire ce qui suit.
stack.Push(temp_stack.pop());
stack.Push(temp_stack.pop());
stack.Push(temp_stack.pop());
stack.pop(); //Pop out 1
stack.pop(); //Pop out 2
stack.pop(); //Pop out 3
Vous pouvez utiliser votre propre classe de personnalisation basée sur le concept, ici l'extrait de code que vous pouvez utiliser pour faire le travail.
/*
* Stack implementation in JavaScript
*/
function Stack(){
this.top = null;
this.count = 0;
this.getCount = function(){
return this.count;
}
this.getTop = function(){
return this.top;
}
this.Push = function(data){
var node = {
data : data,
next : null
}
node.next = this.top;
this.top = node;
this.count++;
}
this.peek = function(){
if(this.top === null){
return null;
}else{
return this.top.data;
}
}
this.pop = function(){
if(this.top === null){
return null;
}else{
var out = this.top;
this.top = this.top.next;
if(this.count>0){
this.count--;
}
return out.data;
}
}
this.displayAll = function(){
if(this.top === null){
return null;
}else{
var arr = new Array();
var current = this.top;
//console.log(current);
for(var i = 0;i<this.count;i++){
arr[i] = current.data;
current = current.next;
}
return arr;
}
}
}
et pour vérifier ceci utilisez votre console et essayez ces lignes une par une.
>> var st = new Stack();
>> st.Push("BP");
>> st.Push("NK");
>> st.getTop();
>> st.getCount();
>> st.displayAll();
>> st.pop();
>> st.displayAll();
>> st.getTop();
>> st.peek();
Voici la version de liste chaînée d'une file d'attente incluant également le dernier nœud, comme suggéré par @perkins et comme il convient le mieux.
// QUEUE Object Definition
var Queue = function() {
this.first = null;
this.last = null;
this.size = 0;
};
var Node = function(data) {
this.data = data;
this.next = null;
};
Queue.prototype.enqueue = function(data) {
var node = new Node(data);
if (!this.first){ // for empty list first and last are the same
this.first = node;
this.last = node;
} else { // otherwise we stick it on the end
this.last.next=node;
this.last=node;
}
this.size += 1;
return node;
};
Queue.prototype.dequeue = function() {
if (!this.first) //check for empty list
return null;
temp = this.first; // grab top of list
if (this.first==this.last) {
this.last=null; // when we need to pop the last one
}
this.first = this.first.next; // move top of list down
this.size -= 1;
return temp;
};
Si vous comprenez les piles avec les fonctions Push () et pop (), la file d'attente sert simplement à effectuer l'une de ces opérations au sens contraire. L'opposant de Push () est unshift () et le contraire de pop () est shift () . Alors:
//classic stack
var stack = [];
stack.Push("first"); // Push inserts at the end
stack.Push("second");
stack.Push("last");
stack.pop(); //pop takes the "last" element
//One way to implement queue is to insert elements in the oposite sense than a stack
var queue = [];
queue.unshift("first"); //unshift inserts at the beginning
queue.unshift("second");
queue.unshift("last");
queue.pop(); //"first"
//other way to do queues is to take the elements in the oposite sense than stack
var queue = [];
queue.Push("first"); //Push, as in the stack inserts at the end
queue.Push("second");
queue.Push("last");
queue.shift(); //but shift takes the "first" element
La structure standard des tableaux en Javascript est une pile (premier entré, dernier sorti) et peut également être utilisée comme file d'attente (premier entré, premier sorti) en fonction des appels que vous passez.
Vérifiez ce lien pour voir comment faire en sorte qu'un tableau se comporte comme une file d'attente:
L'implémentation de la pile est triviale, comme expliqué dans les autres réponses.
Cependant, je n'ai trouvé aucune réponse satisfaisante dans ce fil pour implémenter une file d'attente en javascript, j'ai donc créé la mienne.
Il existe trois types de solutions dans ce fil de discussion:
array.shift()
sur un grand tableau est très inefficaceLes matrices décalées sont la solution la plus satisfaisante dans mon esprit, mais elles stockent toujours tout dans un grand tableau contigu qui peut être problématique, et l'application échelonnera lorsque le tableau sera coupé.
J'ai réalisé une implémentation en utilisant une liste chaînée de petits tableaux (1000 éléments maximum chacun). Les tableaux se comportent comme des tableaux à décalage différé, à la différence qu’ils ne sont jamais coupés: lorsque chaque élément du tableau est supprimé, le tableau est simplement ignoré.
Le paquet est sur npm avec les fonctionnalités de base FIFO, je l’ai récemment poussé. Le code est divisé en deux parties.
Voici la première partie
/** Queue contains a linked list of Subqueue */
class Subqueue <T> {
public full() {
return this.array.length >= 1000;
}
public get size() {
return this.array.length - this.index;
}
public peek(): T {
return this.array[this.index];
}
public last(): T {
return this.array[this.array.length-1];
}
public dequeue(): T {
return this.array[this.index++];
}
public enqueue(elem: T) {
this.array.Push(elem);
}
private index: number = 0;
private array: T [] = [];
public next: Subqueue<T> = null;
}
Et voici la classe Queue
principale:
class Queue<T> {
get length() {
return this._size;
}
public Push(...elems: T[]) {
for (let elem of elems) {
if (this.bottom.full()) {
this.bottom = this.bottom.next = new Subqueue<T>();
}
this.bottom.enqueue(elem);
}
this._size += elems.length;
}
public shift(): T {
if (this._size === 0) {
return undefined;
}
const val = this.top.dequeue();
this._size--;
if (this._size > 0 && this.top.size === 0 && this.top.full()) {
// Discard current subqueue and point top to the one after
this.top = this.top.next;
}
return val;
}
public peek(): T {
return this.top.peek();
}
public last(): T {
return this.bottom.last();
}
public clear() {
this.bottom = this.top = new Subqueue();
this._size = 0;
}
private top: Subqueue<T> = new Subqueue();
private bottom: Subqueue<T> = this.top;
private _size: number = 0;
}
Les annotations de type (: X
) peuvent facilement être supprimées pour obtenir le code javascript de ES6.
Pas de tableau (s)
//Javascript stack linked list data structure (no array)
function node(value, noderef) {
this.value = value;
this.next = noderef;
}
function stack() {
this.Push = function (value) {
this.next = this.first;
this.first = new node(value, this.next);
}
this.pop = function () {
var popvalue = this.first.value;
this.first = this.first.next;
return popvalue;
}
this.hasnext = function () {
return this.next != undefined;
}
this.isempty = function () {
return this.first == undefined;
}
}
//Javascript stack linked list data structure (no array)
function node(value, noderef) {
this.value = value;
this.next = undefined;
}
function queue() {
this.enqueue = function (value) {
this.oldlast = this.last;
this.last = new node(value);
if (this.isempty())
this.first = this.last;
else
this.oldlast.next = this.last;
}
this.dequeue = function () {
var queuvalue = this.first.value;
this.first = this.first.next;
return queuvalue;
}
this.hasnext = function () {
return this.first.next != undefined;
}
this.isempty = function () {
return this.first == undefined;
}
}
Si vous recherchez une implémentation ES6 OOP de la structure de données Stack and Queue avec quelques opérations de base (basées sur des listes chaînées), voici à quoi ça pourrait ressembler:
Queue.js
import LinkedList from '../linked-list/LinkedList';
export default class Queue {
constructor() {
this.linkedList = new LinkedList();
}
isEmpty() {
return !this.linkedList.tail;
}
peek() {
if (!this.linkedList.head) {
return null;
}
return this.linkedList.head.value;
}
enqueue(value) {
this.linkedList.append(value);
}
dequeue() {
const removedHead = this.linkedList.deleteHead();
return removedHead ? removedHead.value : null;
}
toString(callback) {
return this.linkedList.toString(callback);
}
}
Stack.js
import LinkedList from '../linked-list/LinkedList';
export default class Stack {
constructor() {
this.linkedList = new LinkedList();
}
/**
* @return {boolean}
*/
isEmpty() {
return !this.linkedList.tail;
}
/**
* @return {*}
*/
peek() {
if (!this.linkedList.tail) {
return null;
}
return this.linkedList.tail.value;
}
/**
* @param {*} value
*/
Push(value) {
this.linkedList.append(value);
}
/**
* @return {*}
*/
pop() {
const removedTail = this.linkedList.deleteTail();
return removedTail ? removedTail.value : null;
}
/**
* @return {*[]}
*/
toArray() {
return this.linkedList
.toArray()
.map(linkedListNode => linkedListNode.value)
.reverse();
}
/**
* @param {function} [callback]
* @return {string}
*/
toString(callback) {
return this.linkedList.toString(callback);
}
}
Et l'implémentation LinkedList utilisée pour Stack and Queue dans les exemples ci-dessus peut être trouvée sur GitHub ici .
Cordialement,
En Javascript, l'implémentation des piles et des files d'attente est la suivante:
Pile: Une pile est un conteneur d'objets insérés et retirés selon le principe du dernier entré, premier sorti (LIFO).
File d'attente: Une file d'attente est un conteneur d'objets (une collection linéaire) qui sont insérés et supprimés selon le principe du premier entré, premier sorti (FIFO).
Unshift: La méthode ajoute un ou plusieurs éléments au début d'un tableau.
Shift: Method supprime le premier élément d'un tableau.
let stack = [];
stack.Push(1);//[1]
stack.Push(2);//[1,2]
stack.Push(3);//[1,2,3]
console.log('It was inserted 1,2,3 in stack:', ...stack);
stack.pop(); //[1,2]
console.log('Item 3 was removed:', ...stack);
stack.pop(); //[1]
console.log('Item 2 was removed:', ...stack);
let queue = [];
queue.Push(1);//[1]
queue.Push(2);//[1,2]
queue.Push(3);//[1,2,3]
console.log('It was inserted 1,2,3 in queue:', ...queue);
queue.shift();// [2,3]
console.log('Item 1 was removed:', ...queue);
queue.shift();// [3]
console.log('Item 2 was removed:', ...queue);
var x = 10;
var y = 11;
var Queue = new Array();
Queue.unshift(x);
Queue.unshift(y);
console.log(Queue)
// Output [11, 10]
Queue.pop()
console.log(Queue)
// Output [11]
Créez une paire de classes qui fournit les différentes méthodes de chacune de ces structures de données (Push, Pop, Peek, etc.). Maintenant, implémentez les méthodes. Si vous connaissez les concepts derrière la pile/la file d'attente, cela devrait être assez simple. Vous pouvez implémenter la pile avec un tableau et une file d’attente avec une liste chaînée, bien qu’il existe certainement d’autres moyens de le faire. Javascript facilitera cela, car il est faiblement typé, vous n'avez donc pas à vous soucier des types génériques, ce que vous auriez à faire si vous l'implémentiez en Java ou C #.
Il me semble que le tableau intégré convient à une pile. Si vous voulez une file d'attente dans TypeScript, voici une implémentation
/**
* A TypeScript implementation of a queue.
*/
export default class Queue {
private queue = [];
private offset = 0;
constructor(array = []) {
// Init the queue using the contents of the array
for (const item of array) {
this.enqueue(item);
}
}
/**
* @returns {number} the length of the queue.
*/
public getLength(): number {
return (this.queue.length - this.offset);
}
/**
* @returns {boolean} true if the queue is empty, and false otherwise.
*/
public isEmpty(): boolean {
return (this.queue.length === 0);
}
/**
* Enqueues the specified item.
*
* @param item - the item to enqueue
*/
public enqueue(item) {
this.queue.Push(item);
}
/**
* Dequeues an item and returns it. If the queue is empty, the value
* {@code null} is returned.
*
* @returns {any}
*/
public dequeue(): any {
// if the queue is empty, return immediately
if (this.queue.length === 0) {
return null;
}
// store the item at the front of the queue
const item = this.queue[this.offset];
// increment the offset and remove the free space if necessary
if (++this.offset * 2 >= this.queue.length) {
this.queue = this.queue.slice(this.offset);
this.offset = 0;
}
// return the dequeued item
return item;
};
/**
* Returns the item at the front of the queue (without dequeuing it).
* If the queue is empty then {@code null} is returned.
*
* @returns {any}
*/
public peek(): any {
return (this.queue.length > 0 ? this.queue[this.offset] : null);
}
}
Et voici un test Jest
pour cela
it('Queue', () => {
const queue = new Queue();
expect(queue.getLength()).toBe(0);
expect(queue.peek()).toBeNull();
expect(queue.dequeue()).toBeNull();
queue.enqueue(1);
expect(queue.getLength()).toBe(1);
queue.enqueue(2);
expect(queue.getLength()).toBe(2);
queue.enqueue(3);
expect(queue.getLength()).toBe(3);
expect(queue.peek()).toBe(1);
expect(queue.getLength()).toBe(3);
expect(queue.dequeue()).toBe(1);
expect(queue.getLength()).toBe(2);
expect(queue.peek()).toBe(2);
expect(queue.getLength()).toBe(2);
expect(queue.dequeue()).toBe(2);
expect(queue.getLength()).toBe(1);
expect(queue.peek()).toBe(3);
expect(queue.getLength()).toBe(1);
expect(queue.dequeue()).toBe(3);
expect(queue.getLength()).toBe(0);
expect(queue.peek()).toBeNull();
expect(queue.dequeue()).toBeNull();
});
J'espère que quelqu'un trouve cela utile,
À votre santé,
Stu
vous pouvez utiliser WeakMaps pour implémenter la propriété privée dans la classe ES6 et les avantages des propriétés et méthodes String en langage JavaScript, comme ci-dessous:
const _items = new WeakMap();
class Stack {
constructor() {
_items.set(this, []);
}
Push(obj) {
_items.get(this).Push(obj);
}
pop() {
const L = _items.get(this).length;
if(L===0)
throw new Error('Stack is empty');
return _items.get(this).pop();
}
peek() {
const items = _items.get(this);
if(items.length === 0)
throw new Error ('Stack is empty');
return items[items.length-1];
}
get count() {
return _items.get(this).length;
}
}
const stack = new Stack();
//now in console:
//stack.Push('a')
//stack.Push(1)
//stack.count => 2
//stack.peek() => 1
//stack.pop() => 1
//stack.pop() => "a"
//stack.count => 0
//stack.pop() => Error Stack is empty
Voici ma mise en œuvre des piles.
function Stack() {
this.dataStore = [];
this.top = 0;
this.Push = Push;
this.pop = pop;
this.peek = peek;
this.clear = clear;
this.length = length;
}
function Push(element) {
this.dataStore[this.top++] = element;
}
function peek() {
return this.dataStore[this.top-1];
}
function pop() {
return this.dataStore[--this.top];
}
function clear() {
this.top = 0;
}
function length() {
return this.top;
}
var s = new Stack();
s.Push("David");
s.Push("Raymond");
s.Push("Bryan");
console.log("length: " + s.length());
console.log(s.peek());