Cách tốt nhất để triển khai Stack và Queue trong JavaScript là gì?
Tôi đang tìm cách thực hiện thuật toán shunting-yard và tôi sẽ cần các cấu trúc dữ liệu này.
Cách tốt nhất để triển khai Stack và Queue trong JavaScript là gì?
Tôi đang tìm cách thực hiện thuật toán shunting-yard và tôi sẽ cần các cấu trúc dữ liệu này.
Câu trả lời:
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
lấy từ " 9 mẹo javascript bạn có thể không biết "
Javascript có các phương thức đẩy và pop, hoạt động trên các đối tượng mảng Javascript thông thường.
Đối với hàng đợi, xem tại đây:
http://safalra.com/web-design/javascript/queues/
Hàng đợi có thể được triển khai trong JavaScript bằng cách sử dụng các phương thức đẩy và dịch chuyển hoặc các phương thức bật và tắt của đối tượng mảng. Mặc dù đây là một cách đơn giản để thực hiện hàng đợi, nhưng nó rất không hiệu quả đối với hàng đợi lớn - vì các phương thức hoạt động trên mảng, các phương thức shift và unshift di chuyển mọi phần tử trong mảng mỗi khi chúng được gọi.
Queue.js là một triển khai hàng đợi đơn giản và hiệu quả cho JavaScript có hàm dequeue chạy trong thời gian không đổi được khấu hao. Kết quả là, đối với hàng đợi lớn hơn, nó có thể nhanh hơn đáng kể so với sử dụng mảng.
Mảng.
Cây rơm:
var stack = [];
//put value on top of stack
stack.push(1);
//remove value from top of stack
var value = stack.pop();
Xếp hàng:
var queue = [];
//put value on end of queue
queue.push(1);
//Take first value from queue
var value = queue.shift();
push
và pop
phương thức thì vấn đề đã được giải quyết. Tôi không thực sự thấy quan điểm của bạn ở đây.
Nếu bạn muốn tạo cấu trúc dữ liệu của riêng mình, bạn có thể tự xây dựng:
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;
};
Và để xếp hàng:
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;
};
Node
bị xóa khi bật / tắt ... họ sẽ không ngồi quanh bộ nhớ cho đến khi trình duyệt gặp sự cố?
delete
từ khóa, nhưng nó chỉ hữu ích khi đánh dấu một thuộc tính của một đối tượng là không hiện diện, điều này khác với việc chỉ gán undefined
cho thuộc tính . JavaScript cũng có một new
toán tử, nhưng nó chỉ được sử dụng để đặt this
thành một đối tượng trống mới khi gọi một hàm. Trong C ++, bạn cần ghép mọi thứ new
với a delete
, nhưng không phải bằng JavaScript vì GC. Để ngừng sử dụng bộ nhớ trong JavaScript, chỉ cần dừng tham chiếu đối tượng và cuối cùng nó sẽ được lấy lại.
Tôi thực hiện Stackvà Queuesử dụngLinked 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();
Dịch chuyển mảng Javascript () chậm đặc biệt là khi giữ nhiều phần tử. Tôi biết hai cách để thực hiện hàng đợi với độ phức tạp O (1) được khấu hao.
Đầu tiên là bằng cách sử dụng bộ đệm tròn và nhân đôi bảng. Tôi đã thực hiện điều này trước đây. Bạn có thể xem mã nguồn của tôi ở đây https://github.com/kevyuu/rapid-queue
Cách thứ hai là sử dụng hai ngăn xếp. Đây là mã cho hàng đợi với hai ngăn xếp
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;}
Đây là so sánh hiệu suất bằng cách sử dụng jsPerf
Thông tưQueue.shift () so với Array.shift ()
http://jsperf.com/rapidqueue-shift-vs-array-shift
Như bạn có thể thấy nó nhanh hơn đáng kể với tập dữ liệu lớn
Có khá nhiều cách để bạn có thể triển khai Ngăn xếp và Hàng đợi trong Javascript. Hầu hết các câu trả lời ở trên là các triển khai khá nông và tôi sẽ cố gắng thực hiện một cái gì đó dễ đọc hơn (sử dụng các tính năng cú pháp mới của es6) và mạnh mẽ.
Đây là cách thực hiện ngăn xếp:
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;
}
}
Và đây là cách bạn có thể sử dụng ngăn xếp:
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
Nếu bạn muốn xem mô tả chi tiết về việc triển khai này và làm thế nào để cải thiện nó hơn nữa, bạn có thể đọc tại đây: http://jschap.com/data-strucenses-in-javascript-stack/
Đây là mã để thực hiện hàng đợi trong 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
}
}
Đây là cách bạn có thể sử dụng triển khai này:
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
Để xem hướng dẫn đầy đủ về cách các cấu trúc dữ liệu này đã được triển khai và làm thế nào để cải thiện chúng hơn nữa, bạn có thể muốn xem qua phần 'Chơi với cấu trúc dữ liệu trong chuỗi javascript' tại jsch.com. Đây là các liên kết cho hàng đợi - http://jschap.com/playing-data-strucenses-javascript-queues/
Bạn có thể sử dụng lớp tùy chỉnh của riêng bạn dựa trên khái niệm, ở đây đoạn mã mà bạn có thể sử dụng để thực hiện công cụ
/*
* 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;
}
}
}
và để kiểm tra điều này, hãy sử dụng bảng điều khiển của bạn và thử từng dòng một.
>> var st = new Stack();
>> st.push("BP");
>> st.push("NK");
>> st.getTop();
>> st.getCount();
>> st.displayAll();
>> st.pop();
>> st.displayAll();
>> st.getTop();
>> st.peek();
/*------------------------------------------------------------------
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))
Hoặc nếu không, bạn có thể sử dụng hai mảng để thực hiện cấu trúc dữ liệu hàng đợi.
var temp_stack = new Array();
var stack = new Array();
temp_stack.push(1);
temp_stack.push(2);
temp_stack.push(3);
Nếu tôi bật các phần tử bây giờ thì đầu ra sẽ là 3,2,1. Nhưng chúng tôi muốn cấu trúc FIFO để bạn có thể làm như sau.
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
push
sau lần đầu tiênpop
Đây là một cách thực hiện hàng đợi khá đơn giản với hai mục đích:
Việc thực hiện ngăn xếp chỉ chia sẻ mục đích thứ hai.
// 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; };
Việc thực hiện ngăn xếp là tầm thường như được giải thích trong các câu trả lời khác.
Tuy nhiên, tôi không tìm thấy bất kỳ câu trả lời thỏa đáng nào trong chuỗi này để thực hiện một hàng đợi trong javascript, vì vậy tôi đã tự tạo ra.
Có ba loại giải pháp trong chủ đề này:
array.shift()
trên một mảng lớn là rất không hiệu quả.Mảng dịch chuyển bị trì hoãn là giải pháp thỏa đáng nhất trong tâm trí tôi, nhưng chúng vẫn lưu trữ mọi thứ trong một mảng lớn liền kề có thể gây ra vấn đề và ứng dụng sẽ loạng choạng khi mảng bị cắt.
Tôi đã thực hiện bằng cách sử dụng danh sách các mảng nhỏ được liên kết (tối đa 1000 phần tử mỗi mảng). Các mảng hoạt động giống như các mảng dịch chuyển bị trì hoãn, ngoại trừ chúng không bao giờ bị cắt: khi mọi phần tử trong mảng bị loại bỏ, mảng sẽ bị loại bỏ.
Gói hàng vào npm với chức năng FIFO cơ bản, tôi mới đẩy nó gần đây. Mã được chia thành hai phần.
Đây là phần đầu tiên
/** 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;
}
Và đây là Queue
lớp chính :
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;
}
: X
Có thể dễ dàng xóa các chú thích ( ) để lấy mã javascript ES6.
Nếu bạn hiểu các ngăn xếp với các hàm push () và pop (), thì hàng đợi chỉ là để thực hiện một trong các thao tác này theo nghĩa đối diện. Đối diện của đẩy () là unshift () và đối diện với pop () es shift (). Sau đó:
//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
.shift()
phương pháp không phải là một việc thực hiện hàng đợi thích hợp. Đó là O (n) chứ không phải O (1) và sẽ chậm đối với các hàng đợi lớn.
Đây là phiên bản danh sách được liên kết của hàng đợi cũng bao gồm nút cuối cùng, như được đề xuất bởi @perkins và khi thích hợp nhất.
// 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;
};
Nếu bạn đang tìm kiếm ES6 OOP triển khai cấu trúc dữ liệu Stack và Queue với một số thao tác cơ bản (dựa trên danh sách được liên kết) thì có thể như sau:
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);
}
}
Và triển khai LinkedList được sử dụng cho Stack và Queue trong các ví dụ ở trên có thể được tìm thấy trên GitHub tại đây .
Không có mảng
//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;
}
}
Cấu trúc mảng thông thường trong Javascript là một Stack (đầu tiên vào trước, cuối cùng) và cũng có thể được sử dụng như một hàng đợi (đầu tiên vào, ra trước) tùy thuộc vào các cuộc gọi bạn thực hiện.
Kiểm tra liên kết này để xem cách làm cho một mảng hoạt động như một hàng đợi:
Trân trọng,
Trong Javascript, việc thực hiện các ngăn xếp và hàng đợi như sau:
Ngăn xếp: Ngăn xếp là một thùng chứa các đối tượng được chèn và loại bỏ theo nguyên tắc nhập trước xuất trước (LIFO).
Hàng đợi: Hàng đợi là một thùng chứa các đối tượng (một bộ sưu tập tuyến tính) được chèn và loại bỏ theo nguyên tắc nhập trước xuất trước (FIFO).
Unshift: Phương thức thêm một hoặc nhiều phần tử vào đầu một mảng.
Shift: Phương thức loại bỏ phần tử đầu tiên khỏi một mảng.
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]
Dường như với tôi rằng mảng dựng sẵn là tốt cho một ngăn xếp. Nếu bạn muốn một hàng đợi trong TypeScript thì đây là một triển khai
/**
* 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);
}
}
Và đây là một Jest
thử nghiệm cho nó
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();
});
Hy vọng ai đó thấy điều này hữu ích,
Chúc mừng
Stu
Tạo một cặp lớp cung cấp các phương thức khác nhau mà mỗi cấu trúc dữ liệu này có (đẩy, bật, nhìn trộm, v.v.). Bây giờ thực hiện các phương pháp. Nếu bạn quen thuộc với các khái niệm đằng sau ngăn xếp / hàng đợi, điều này sẽ khá đơn giản. Bạn có thể triển khai ngăn xếp với một mảng và một hàng đợi với một danh sách được liên kết, mặc dù chắc chắn có nhiều cách khác để thực hiện. Javascript sẽ làm cho việc này trở nên dễ dàng, vì nó được gõ yếu, do đó bạn thậm chí không phải lo lắng về các loại chung chung, điều mà bạn phải làm nếu bạn triển khai nó trong Java hoặc C #.
Đây là triển khai ngăn xếp của tôi.
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());
bạn có thể sử dụng WeakMaps để triển khai thuộc tính riêng tư trong lớp ES6 và lợi ích của các phương thức và phương thức chuỗi trong ngôn ngữ JavaScript như dưới đây:
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
Xây dựng một hàng đợi bằng cách sử dụng hai ngăn xếp.
O (1) cho cả hoạt động enqueue và dequeue.
class Queue {
constructor() {
this.s1 = []; // in
this.s2 = []; // out
}
enqueue(val) {
this.s1.push(val);
}
dequeue() {
if (this.s2.length === 0) {
this._move();
}
return this.s2.pop(); // return undefined if empty
}
_move() {
while (this.s1.length) {
this.s2.push(this.s1.pop());
}
}
}