数据结构堆栈 内存堆栈
by Kevin Turney
凯文·特尼(Kevin Turney)
数据结构101:堆栈 (Data Structures 101: Stacks)
堆栈是计算机科学中最基本的数据结构。 (A Stack is the most elemental of the data structures in computer science.)
Data structures are a way to organize our information. They provide a means of storing different types of data in unique ways and methods to access either all or distinct parts of it.
数据结构是组织信息的一种方式。 它们提供了一种以独特的方式和方法存储不同类型数据的方法,以访问其全部或不同部分。
从堆栈开始 (Starting with a Stack)
Have you ever used a stack? Of course! Your email is a form of a stack, new mail comes in and is placed on top. When you finish reading the latest email, you remove it from the top. In development, whenever you call a function, that is placed on a stack in the engine that processes the code.
您曾经使用过堆栈吗? 当然! 您的电子邮件是一种堆栈形式,新邮件进入并放置在顶部。 阅读完最新的电子邮件后,请从顶部将其删除。 在开发中,无论何时调用函数,该函数都会放在处理代码的引擎中的堆栈中。
How we use stacks is a Last In, First Out processing system.
我们如何使用堆栈是一个后进先出处理系统。
An analogy would be a recipe. Suppose we want to make a bowl of spaghetti. What are the steps?
打个比方就是一个菜谱。 假设我们要煮一碗意大利面。 步骤是什么?
- Get a pot 拿一个锅
- Add water 加水
- Bring water to a boil 把水烧开
- Add salt to the water 加盐到水中
- Add spaghetti 添加意大利面
- Cook spaghetti till tender 将意大利面煮至嫩
Now when the spaghetti is done, we have to get back to where we started, a clean kitchen. We need a method to organize our task list and help us get back to where we left off.
现在,义大利面煮好之后,我们必须回到开始的地方,一个干净的厨房。 我们需要一种方法来组织任务列表,并帮助我们回到上一个中断的地方。
JavaScript is a single threaded language. In the simplest terms, it means it can only do one thing at a time, just like us. So how does our language of choice handle this in an organized way, Stacks?
JavaScript是一种单线程语言。 用最简单的话说,它一次只能做一件事情,就像我们一样。 那么,我们选择的语言如何以一种有组织的方式来处理此问题呢?
As you can see, the stack is a clean way of handling tasks, removing them, and eventually getting back to the beginning.
如您所见,堆栈是一种处理任务,将其删除并最终重新开始的干净方法。
Stacks come with a cost: memory. For every item we place on the stack, we allocate a stack frame to it. Think of an array index. Each index is allocated space to hold something. If we keep adding and adding to a stack, we hold the possibility of running out of space, like a parking lot that is full. When that happens, we have an overflow, hence, the term “stack overflow”. This can lead to crashes and stuck processes.
堆栈要付出代价:内存。 对于放置在堆栈上的每个项目,我们都会为其分配一个堆栈框架。 想想一个数组索引。 每个索引都分配了容纳某些内容的空间。 如果我们不断增加和增加堆栈,则可能会出现空间不足的情况,例如停车场已满。 发生这种情况时,我们会发生溢出,因此称为“堆栈溢出”。 这可能导致崩溃和进程卡死。
How do we reclaim memory? When an item is removed from the stack, JavaScript uses “garbage collection” to free up resources and reclaim the storage space previously used.
我们如何回收内存? 当从堆栈中删除项目时,JavaScript使用“垃圾收集”释放资源并回收以前使用的存储空间。
实作 (Implementation)
First, how do we store the data? What can we use in JavaScript to hold data? We can use native objects like arrays, which we are familiar with and use built-in methods, push and pop. Ok, I guess we’re done, see you later…
首先,我们如何存储数据? 我们可以在JavaScript中使用什么来保存数据? 我们可以使用熟悉的数组之类的本机对象,并使用内置方法push和pop。 好吧,我想我们已经完成了,待会见...
Nah, to understand how a stack works under the hood, we use the base Object form.
不,要了解堆栈如何在后台运行,我们使用基本的Object形式。
We need a constructor to establish the storage mechanism and properties upon its invocation.
我们需要一个构造函数来在调用它时建立存储机制和属性。
const Stack = function(capacity) { this.storage = {}; this.capacity = capacity || Infinity; this._count = 0;}
This constitues a stack storage mechanism. How can we push data into the stack in a LIFO manner? Add push to the prototype of Stack.
这构成了堆栈存储机制。 我们如何以LIFO方式将数据推入堆栈? 将推添加到Stack的原型。
Stack.prototype.push = function(value) { if (this._count < this._capacity){ this.storage[this._count++] = value; return this._count; } return "Max capacity reached, please remove a value before inserting a new value";}
The push method checks our capacity. If true, we add the value to storage and return how many items are in the stack.
push方法检查我们的能力。 如果为true,则将值添加到存储并返回堆栈中有多少项。
[this._count++] is first evaluated as 0, and we use the postfix operator, ++ to increment the count. Our stack has a value at this.storage[‘0’], and we return 1 because we have one item in our stack.
[this._count ++]首先被评估为0,我们使用后缀运算符++来增加计数。 我们的堆栈在this.storage ['0']处有一个值,因为堆栈中只有一项,所以我们返回1。
Let’s remove items or ‘pop’ them off the stack.
让我们删除项目或将其“弹出”堆栈。
Stack.prototype.pop = function() { let value = this.storage[--this._count]; delete this.storage[this._count]; if (this._count < 0) { this._count = 0; } return value;}
With pop, we store the last value on the stack. If we remove it first, we won’t have it as a return value. Because of the prefix operator, — , we find the value of this.count and decrement it first before evaluating it. If we have this.count === 1, this.storage[ — this.count] is evalutated as this.storage[‘0’].
使用pop,我们将最后一个值存储在堆栈中。 如果先删除它,就不会将其作为返回值。 由于存在前缀运算符—,我们找到了this.count的值,并在对其求值之前先对其进行了递减。 如果我们有this.count === 1,则将this.storage [— this.count]评估为this.storage ['0']。
What about seeing what’s on the top of the stack? The interface for that is ‘peek’.
看看堆栈顶部是什么? 界面是“窥视”。
Stack.prototype.peek = function() { return this.storage[this._count -1]}
Lastly, count…
最后,算一下...
Stack.prototype.count = function(){ return this._count;}
The full implementation ES6 style with class Stack:
带有类Stack的完整ES6样式实现:
class Stack { constructor(capacity) { this.storage = {}; this._count = 0; this.capacity = capacity || Infinity; }
push(value) { if (this._count < this.capacity){ this.storage[this._count++] = value; return this._count; } return "Max capacity reached, please remove a value before inserting a new value"; }
pop() { let value = this.storage[--this._count]; delete this.storage[this._count]; if (this._count < 0) { this._count = 0; } return value; } peek() { return this.storage[this._count - 1]; } count() { return this._count; }};let stack = new Stack();stack; // Stack { storage: {}, _count: 0, capacity: Infinity }stack.push('yea')stack.push('oh yea');
stack; // Stack {storage: { 0: 'yea', 1: 'oh yea' }, _count: 2, capacity: Infinity }
stack.pop(); // 'oh yea'stack; // Stack { storage: { 0: 'yea' }, _count: 1, capacity: Infinity }
stack.push('nope');stack.push('yup');stack; // Stack {storage: { 0: 'yea', 1: 'nope', 2: 'yup' }, _count: 3, capacity: Infinity }
stack.count(); // 3stack.peek(); // 'yup'stack; // Stack {storage: { 0: 'yea', 1: 'nope', 2: 'yup' }, _count: 3, capacity: Infinity }
Thank you for reading this article. My goal was to give a clear uncluttered explanation of Stacks, their use, and why we need them. Next up: Queues.
感谢您阅读本文。 我的目标是对栈,栈的使用以及为什么需要栈进行清晰,清晰的解释。 接下来:队列 。
翻译自: https://www.freecodecamp.org/news/data-structures-101-stacks-696b3282980/
数据结构堆栈 内存堆栈