堆栈队列
Stacks and queues are often taught in the same breath. They are a relatively simple data structure each of which only needs two methods to be functional by definition. We need a way to put something in and then take something out.
堆栈和队列通常在同一时间传授。 它们是一个相对简单的数据结构,每个结构只需要两种方法即可定义。 我们需要一种放入东西然后取出东西的方法。
A few real-world examples of these data structures:
这些数据结构的一些实际示例:
Stack:
堆栈:
A pile of plates in a cafeteria. When you remove a dish from the stack you are going to take the one from the top ( since removing from the bottom would cause a mess ). This is to say the last plate added to the stack is removed first. This means a stack operates on the LIFO principle.
自助餐厅自助餐牌照堆。 从堆叠中取出盘子时,您要从顶部取出一个(因为从底部取出会造成混乱)。 也就是说添加到堆栈中的最后一块板首先被移除。 这意味着堆栈将按照LIFO原理运行。
Last
最后
In
I N
First
第一
Out
ØUT
Queues:
队列:
If you’ve ever waited in a line you have been a node in a queue. Think checkout line. The first person in line is going to be the one that is served first. If you recently joined a line and are fifth you need to wait for the four people ahead of you to be served. Thankfully, queues ( and lines ) operate on a FIFO principle.
如果您一直在排队等候,那么您已经是队列中的一个节点。 认为结帐行。 排队的第一个人将是第一个被服务的人。 如果您最近加入了队伍,并且排名第五,则需要等待前面的四个人被送达。 值得庆幸的是,队列(和行)是按照FIFO原理运行的。
First
第一
In
I N
First
第一
Out
ØUT
Let’s Code a Stack Class
让我们编写一个堆栈类
//nodes are going to represent our items in the stack.
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
class Stack {
constructor() {
this.first = null;
this.last = null;
this.size = 0;
}
}
Above is the blueprint to get us started for our Stack data structure. At its core, a Stack is a special variant of a singly linked list. We are simply only going to have methods for adding and removing to/from the top of the stack.
以上是使我们开始使用Stack数据结构的蓝图。 堆栈的核心是单链列表的特殊变体。 我们仅将拥有添加到堆栈顶部和从堆栈顶部移除的方法。
Let’s start with add()
since you can’t remove()
from an empty Stack
让我们从add()
开始,因为您不能从一个空的Stack
remove()
add()
Pseudocode:
add()
伪代码:
// define a function called add
; it takes a value
as an argument// create a new Node
using the passed in value// if the stack is empty; set the first
and the last
to the new Node// otherwise; save this.first
to a variable then re-assign this.first
to our new Node
//new Node
should point to our oldFirst
// increment the size
of the stack// return
the size
of the stack
//定义一个名为add
的函数; 它使用一个value
作为参数//如果栈为空,则使用传入的值//创建一个新的Node
; 将第first
和last
设置为新的Node //;否则; 保存this.first
到一个变量,然后重新分配this.first
我们的新Node
//新的Node
应该指向我们的oldFirst
//增量size
的堆栈// return
的size
的堆栈
In the above pseudocode, we are making a stack that is going to add and remove from the top ( this.first ) of the stack. * Remember that singly-linked lists are not great at removing from the end of the list since we do not have a previous property to easily get the second to last node ( which would become our new tail ). Adding to and removing from the top ( this.first ) allows us to do it in constant time.
在上面的伪代码中,我们正在制作一个堆栈,该堆栈要从堆栈的顶部(this.first)添加和删除。 *请记住,单链列表不能很好地从列表末尾删除,因为我们没有先前的属性来轻松获取倒数第二个节点(这将成为我们的新尾巴)。 添加到顶部(this.first)或从顶部删除(this.first)使我们能够在恒定的时间内完成此操作。
While we’re at it lets hash out the remove()
pseudocode
在此过程中,让我们哈希出remove()
伪代码
remove()
Pseudocode:
remove()
伪代码:
// define a function called remove()
; it takes no arguments// if the stack is empty; return null
// assign the first
item in the stack to a variable// if there is only one item in the stack; set this.last
to null
// then re-assign this.first
to oldFirst.next
// decrement the size
// return
the value
of the oldFirst
//定义一个称为remove()
的函数; 如果堆栈为空,则不接受任何参数; return null
//如果堆栈中只有一个项目,则将堆栈中的first
项分配给变量//; this.last
设置为null
//然后将this.first
重新分配给oldFirst.next
//减小size
// return
oldFirst
的value
Here we are making sure we are removing in constant time as well. We need to make sure if we are emptying the list we also remove the connection to this.last
as well.
在这里,我们确保也要在固定时间内删除。 我们需要确保是否要清空列表,我们也要删除与此this.last
的连接。
Here’s my implementation:
这是我的实现:
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
//were going to use the front of the list because we want the adding and the removal to be constant time
class Stack {
constructor() {
this.first = null;
this.last = null;
this.size = 0;
}
// add to the 'top' of the stack (this.first represents the top of the stack)
add(val) {
// create a node to add to the stack
let newNode = new Node(val);
if (!this.first) {
this.first = newNode;
this.last = newNode;
} else {
let oldFirst = this.first;
this.first = newNode;
newNode.next = oldFirst;
}
return ++this.size
}
//remove the last item that was added to our stack
//in our implementation this is called this.first
remove() {
if(!this.first) return null;
let oldFirst = this.first;
if(this.size === 1){
this.last = null;
}
this.first = oldFirst.next
this.size--;
return oldFirst.val;
}
}
Queues similarly have only need a method to add to and remove from the queue. The difference is that queues need to add()
to the end and remove from the beginning. This will ensure we have the LIFO methodology mentioned above.
同样,队列只需要一种添加到队列或从队列中删除的方法。 不同之处在于,队列需要在末尾add()
并从头开始删除。 这将确保我们拥有上述的LIFO方法。
Let’s put together our blueprint for the Queue
class
让我们整理一下Queue
类的蓝图
class Node {
constructor(val){
this.val = val;
this.next = null
}
}
class Queue {
constructor(){
this.first = null; // this has the highest priority to get out of the queue
this.last = null; // this is the lowest priority in the queue
this.size = 0;
}
}
Let’s talk about our add()
and remove()
methods
让我们谈谈add()
和emove()
方法
add()
Pseudocode:
add()
伪代码:
// define a function called add()
; it takes a value as an argument// create a new Node
using the value passed in// if the Queue
is empty set this.first
and this.last
to our new Node// otherwise add the new Node to the end of our list
//定义一个名为add()
的函数; 它以一个值作为参数///使用传入的值创建一个新的Node
//如果Queue
为空,请将this.first
和this.last
设置为我们的新Node// otherwise add the new Node to the end of our list
remove()
Pseudocode:
remove()
伪代码:
// define a function called remove()
; it takes no argument// if the queue
is empty; return null
// store the oldFirst
in a variable// if there is only one node in the queue set this.last
to null// set this.first
to the next node
in the queue// decrement the size
of the queue// return oldFirst.val
//定义一个称为remove()
的函数; 如果queue
为空,则不带参数。 返回null
//将oldFirst
存储在变量中//如果队列中只有一个节点,则将this.last
设置为null //将this.first
设置为队列中的下一个node
//减小队列的size
//返回oldFirst.val
Our queue is going to add to the end of the list ( this.last
) and remove it from the front of the queue
. This obeys our FIFO methodology.
我们的队列将添加到列表的末尾( this.last
)并将其从queue
this.last
删除。 这符合我们的FIFO方法。
Here’s my implementation:
这是我的实现:
// nodes are going to represent the items in our Queue class
class Node {
constructor(val){
this.val = val;
this.next = null
}
}
class Queue {
constructor(){
this.first = null; // this has the highest priority to get out of the queue
this.last = null; // this is the lowest priority in the queue
this.size = 0;
}
// add a value to the end of the queue ( becomes the new this.last)
enqueue(val){
let newNode = new Node(val)
if(!this.first){
this.first = newNode;
this.last = newNode;
} else {
this.last.next = newNode;
this.last = newNode;
}
return ++this.size
}
// removes a value from the beginning of the queue (this.first)
dequeue(){
if(!this.first) return null;
let oldFirst = this.first;
if(this.first === this.last) {
this.last = null;
}
//take the first item and re-assign it to the next item in the list
this.first = this.first.next;
this.size--;
return oldFirst.val;
}
}
Queues and Stacks are simple structures with some basic functionality but will be used as a component to other larger and more complex data structures. If you want to check out more about them I’ll link to more articles about them in the coming weeks.
队列和堆栈是具有某些基本功能的简单结构,但将用作其他更大,更复杂的数据结构的组成部分。 如果您想了解更多有关它们的信息,我将在接下来的几周内链接到有关它们的更多文章。
快乐黑客 (Happy Hacking)
翻译自: https://medium.com/@robert.keller22/a-short-guide-to-stacks-queues-459f8df2081b
堆栈队列