วิธีที่ดีที่สุดในการนำ Stack และ Queue ไปใช้ใน JavaScript คืออะไร?
ฉันกำลังมองหาอัลกอริธึมการหลบหลีกและฉันต้องการโครงสร้างข้อมูลเหล่านี้
วิธีที่ดีที่สุดในการนำ Stack และ Queue ไปใช้ใน JavaScript คืออะไร?
ฉันกำลังมองหาอัลกอริธึมการหลบหลีกและฉันต้องการโครงสร้างข้อมูลเหล่านี้
คำตอบ:
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
นำมาจาก " 9 javascript tips ที่คุณอาจไม่รู้ "
Javascript มีวิธีการพุชและป๊อปซึ่งทำงานกับออบเจ็กต์อาร์เรย์ของ Javascript ทั่วไป
สำหรับคิวดูที่นี่:
http://safalra.com/web-design/javascript/queues/
คิวสามารถนำมาใช้ใน JavaScript โดยใช้วิธีการผลักและเปลี่ยนหรือวิธีการ unshift และป๊อปอัพของวัตถุอาร์เรย์ แม้ว่านี่จะเป็นวิธีที่ง่ายในการใช้คิว แต่ก็ไม่มีประสิทธิภาพมากสำหรับคิวขนาดใหญ่ - เนื่องจากวิธีการทำงานในอาร์เรย์วิธีการ shift และ unshift จะย้ายองค์ประกอบทุกอย่างในอาร์เรย์ทุกครั้งที่มีการเรียกใช้
Queue.js เป็นการใช้งานคิวที่ง่ายและมีประสิทธิภาพสำหรับ JavaScript ซึ่งฟังก์ชัน dequeue ทำงานในเวลาคงที่ที่ถูกตัดจำหน่าย เป็นผลให้สำหรับคิวที่มีขนาดใหญ่กว่ามันสามารถเร็วกว่าการใช้อาร์เรย์อย่างมีนัยสำคัญ
อาร์เรย์
ซ้อนกัน:
var stack = [];
//put value on top of stack
stack.push(1);
//remove value from top of stack
var value = stack.pop();
คิว:
var queue = [];
//put value on end of queue
queue.push(1);
//Take first value from queue
var value = queue.shift();
push
และpop
วิธีการแก้ไขปัญหาที่เกิดขึ้นแล้ว ฉันไม่เห็นจุดของคุณที่นี่
หากคุณต้องการสร้างโครงสร้างข้อมูลของคุณเองคุณสามารถสร้างของคุณเอง:
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;
};
และสำหรับคิว:
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
ลบเมื่อ popping / dequeuing ... พวกเขาจะไม่นั่งรอบหน่วยความจำ hogging จนกว่าเบราว์เซอร์ล่มหรือไม่
delete
คำหลัก แต่มีประโยชน์เฉพาะในการทำเครื่องหมายคุณสมบัติของวัตถุว่าไม่เป็นปัจจุบันซึ่งแตกต่างจากการกำหนดundefined
ให้กับคุณสมบัติเท่านั้น จาวาสคริปต์ยังมีnew
โอเปอเรเตอร์ แต่มันถูกใช้เพื่อตั้งค่าthis
เป็นวัตถุว่างเปล่าใหม่เมื่อเรียกใช้ฟังก์ชัน ใน C ++ คุณต้องจับคู่ทุกตัวnew
ด้วย a delete
แต่ไม่ได้อยู่ใน JavaScript เพราะ GC หากต้องการหยุดใช้หน่วยความจำใน JavaScript เพียงหยุดการอ้างอิงวัตถุและในที่สุดก็จะถูกเรียกคืน
การใช้StackและการQueueใช้งานของฉัน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();
Javascript array shift () ช้าโดยเฉพาะเมื่อถือองค์ประกอบหลายอย่าง ฉันรู้วิธีนำคิวมาใช้สองวิธีด้วยความซับซ้อนของ O (1) ที่ถูกตัดจำหน่าย
อย่างแรกคือการใช้บัฟเฟอร์วงกลมและตารางเพิ่มเป็นสองเท่า ฉันได้ดำเนินการนี้มาก่อน คุณสามารถดูซอร์สโค้ดของฉันได้ที่นี่ https://github.com/kevyuu/rapid-queue
วิธีที่สองคือโดยใช้สองกอง นี่คือรหัสสำหรับคิวที่มีสองสแต็ก
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;}
นี่เป็นการเปรียบเทียบประสิทธิภาพโดยใช้ jsPerf
CircularQueue.shift () vs Array.shift ()
http://jsperf.com/rapidqueue-shift-vs-array-shift
อย่างที่คุณเห็นมันเป็นชุดข้อมูลขนาดใหญ่ที่เร็วกว่ามาก
มีหลายวิธีที่คุณสามารถใช้สแต็กและคิวใน Javascript ได้ คำตอบข้างต้นส่วนใหญ่เป็นการใช้งานที่ค่อนข้างตื้นและฉันจะลองใช้สิ่งที่อ่านได้ง่ายขึ้น (โดยใช้คุณสมบัติไวยากรณ์ใหม่ของ es6) และมีประสิทธิภาพ
นี่คือการใช้สแต็ก:
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;
}
}
และนี่คือวิธีที่คุณสามารถใช้สแต็ก:
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
หากคุณต้องการดูคำอธิบายโดยละเอียดเกี่ยวกับการใช้งานนี้และวิธีการปรับปรุงเพิ่มเติมคุณสามารถอ่านได้ที่นี่: http://jschap.com/data-structures-in-javascript-stack/
นี่คือรหัสสำหรับการใช้คิวใน 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
}
}
นี่คือวิธีที่คุณสามารถใช้การใช้งานนี้:
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
หากต้องการดูบทแนะนำที่สมบูรณ์เกี่ยวกับวิธีการใช้โครงสร้างข้อมูลเหล่านี้และวิธีการปรับปรุงเหล่านี้เพิ่มเติมคุณอาจต้องการดูชุดข้อมูล 'การเล่นกับโครงสร้างข้อมูลใน javascript' ที่ jschap.com นี่คือลิงค์สำหรับคิว - http://jschap.com/playing-data-structures-javascript-queues/
คุณสามารถใช้คลาสการปรับแต่งของคุณเองตามแนวคิดนี่คือข้อมูลโค้ดที่คุณสามารถใช้ในการทำสิ่งต่างๆ
/*
* 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;
}
}
}
และเพื่อตรวจสอบนี้ใช้คอนโซลของคุณและลองบรรทัดเหล่านี้หนึ่งโดยหนึ่ง
>> 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))
หรือมิฉะนั้นคุณสามารถใช้สองอาร์เรย์เพื่อใช้โครงสร้างข้อมูลคิว
var temp_stack = new Array();
var stack = new Array();
temp_stack.push(1);
temp_stack.push(2);
temp_stack.push(3);
ถ้าฉันเปิดองค์ประกอบตอนนี้ผลลัพธ์จะเป็น 3,2,1 แต่เราต้องการโครงสร้าง FIFO เพื่อให้คุณสามารถทำสิ่งต่อไปนี้
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
เป็นครั้งแรกหลังจากคุณpop
นี่คือการใช้คิวที่ค่อนข้างง่ายโดยมีเป้าหมายสองประการ:
การใช้งานสแต็กแบ่งปันเป้าหมายที่สองเท่านั้น
// 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; };
การใช้สแต็กนั้นเป็นเรื่องเล็กน้อยตามที่อธิบายไว้ในคำตอบอื่น ๆ
อย่างไรก็ตามฉันไม่พบคำตอบที่น่าพอใจในกระทู้นี้เพื่อใช้คิวในจาวาสคริปต์ดังนั้นฉันจึงสร้างของตัวเอง
มีวิธีแก้ปัญหาสามประเภทในชุดข้อความนี้:
array.shift()
กับอาร์เรย์ขนาดใหญ่นั้นไม่มีประสิทธิภาพมากอาร์เรย์เลื่อนที่ล่าช้าเป็นวิธีแก้ปัญหาที่น่าพอใจที่สุดในใจ แต่ก็ยังเก็บทุกอย่างไว้ในอาร์เรย์ขนาดใหญ่ที่ต่อเนื่องกันซึ่งอาจเป็นปัญหาได้และแอปพลิเคชั่นจะซวนเซ
ฉันใช้งานโดยใช้รายการที่เชื่อมโยงของอาร์เรย์ขนาดเล็ก (แต่ละอิลิเมนต์สูงสุดไม่เกิน 1,000 องค์ประกอบ) อาร์เรย์ทำหน้าที่เหมือนอาร์เรย์เลื่อนการทำงานล่าช้ายกเว้นจะไม่มีการแบ่งเป็นส่วน ๆ : เมื่อทุกองค์ประกอบในอาเรย์ถูกลบอาเรย์จะถูกยกเลิก
แพคเกจอยู่ในเวลา 17.00 น.พร้อมฟังก์ชั่นพื้นฐานของ FIFO ฉันเพิ่งผลักมันไปไม่นาน รหัสจะแบ่งออกเป็นสองส่วน
นี่คือส่วนแรก
/** 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;
}
และนี่คือQueue
คลาสหลัก:
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
) สามารถลบออกได้อย่างง่ายดายเพื่อรับรหัสจาวาสคริปต์ ES6
หากคุณเข้าใจสแต็คที่มีฟังก์ชัน push () และ pop () แสดงว่าคิวนั้นเป็นเพียงการทำให้หนึ่งในการดำเนินการเหล่านี้มีความหมายในทิศทางตรงกันข้าม Oposite of push () คือ unshift () และ oposite ของ pop () es shift () แล้ว:
//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()
วิธีการไม่ได้เป็นการดำเนินการที่เหมาะสมคิว มันคือ O (n) มากกว่า O (1) และจะช้าสำหรับคิวขนาดใหญ่
นี่คือเวอร์ชันรายการที่เชื่อมโยงของคิวซึ่งรวมถึงโหนดสุดท้ายตามที่ @perkins แนะนำและเหมาะสมที่สุด
// 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;
};
หากคุณกำลังมองหาการนำ ES6 OOP ไปใช้กับโครงสร้างข้อมูล Stack และ Queue ด้วยการดำเนินการพื้นฐานบางอย่าง (ตามรายการที่ลิงก์) มันอาจมีลักษณะเช่นนี้:
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);
}
}
และ LinkedList การดำเนินงานที่ใช้สำหรับการกองและคิวในตัวอย่างข้างต้นอาจจะพบได้บน GitHub ที่นี่
ไม่มีอาเรย์
//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;
}
}
โครงสร้างอาเรย์ปกติใน Javascript คือสแต็ก (เข้าก่อน, ออกก่อน) และยังสามารถใช้เป็นคิว (เข้าก่อนเข้าก่อน) ขึ้นอยู่กับการโทรของคุณ
ตรวจสอบลิงค์นี้เพื่อดูวิธีการทำ Array ให้เหมือนกับ Queue:
ความนับถือ,
ใน Javascript การใช้สแต็กและคิวมีดังนี้:
สแต็ค:สแต็กเป็นคอนเทนเนอร์ของวัตถุที่ถูกแทรกและลบออกตามหลักการ last-in-first-out (LIFO)
คิว:คิวเป็นคอนเทนเนอร์ของวัตถุ (คอลเลกชันเชิงเส้น) ที่ถูกแทรกและลบออกตามหลักการ first-in-first-out (FIFO)
Unshift: วิธีการเพิ่มองค์ประกอบอย่างน้อยหนึ่งองค์ประกอบไปยังจุดเริ่มต้นของอาร์เรย์
Shift: เมธอดจะลบองค์ประกอบแรกออกจากอาร์เรย์
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]
ดูเหมือนว่าฉันจะสร้างอาร์เรย์ในตัวสำหรับสแต็ก หากคุณต้องการคิวใน TypeScript นี่คือการใช้งาน
/**
* 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);
}
}
และนี่คือบทJest
ทดสอบสำหรับมัน
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();
});
หวังว่าบางคนพบว่ามีประโยชน์นี้
ไชโย
Stu
สร้างคลาสที่ให้วิธีการต่าง ๆ ที่แต่ละโครงสร้างข้อมูลเหล่านี้มี (push, pop, peek, ฯลฯ ) ตอนนี้ใช้วิธีการ หากคุณคุ้นเคยกับแนวคิดที่อยู่เบื้องหลังสแต็ก / คิวสิ่งนี้ควรตรงไปตรงมา คุณสามารถใช้กองซ้อนกับอาร์เรย์และคิวที่มีรายการที่เชื่อมโยงแม้ว่าจะมีวิธีอื่น ๆ Javascript จะทำให้ง่ายขึ้นเพราะพิมพ์ได้อย่างอ่อนดังนั้นคุณไม่ต้องกังวลเกี่ยวกับประเภททั่วไปซึ่งคุณต้องทำหากคุณนำไปใช้ใน Java หรือ C #
นี่คือการใช้งานกองของฉัน
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());
คุณสามารถใช้ WeakMaps เพื่อนำทรัพย์สินส่วนตัวไปใช้ในคลาส ES6 และประโยชน์ของการใช้สตริงและวิธีการในภาษาจาวาสคริปต์ดังต่อไปนี้:
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
สร้างคิวโดยใช้สองกอง
O (1) สำหรับการดำเนินงานทั้งคิวและคิว
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());
}
}
}