小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
数据结构分类
传统数据结构分为以下几类:
- 数组 Array
- 堆栈:Stack
- 队列:Queue
- 链表:Linked Lists
- 树:Trees
- 图:Graphs
- 散列表(哈希表):Hash Tables
栈和队列
堆栈和队列是一种操作受限的线性结构,JavaScript 中没有内置这样的数据结构,因此我们来实现下。
栈
栈是一种操作受限的线性结构,限定只能在尾部进行插入和删除操作,尾部被称为栈顶,而头部称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,从一个栈删除元素又称作出栈或退栈。这种受限的操作方式让栈元素的入栈出栈遵循一种特殊的原则——先进后出(First In Last Out,FILO)。
栈的应用非常广泛,这里列举 3 种:
- 浏览器的历史记录,它的前进、后退功能就是一个栈操作;
- V8 中的函数执行过程采用的栈结构;
- JavaScript 在捕获代码异常时,详细信息会以调用栈的形式打印。
栈可以通过数组来实现,下面的代码实现了一个栈结构:
class Stack {
constructor(...args) {
// 使用数组进行模拟
this.stack = [...args]
}
push(...items) {
// 入栈
return this.stack.push(... items)
}
pop() {
// 出栈,从数组尾部弹出一项
return this.stack.pop()
}
peek() {
return this.isEmpty()
? undefined
: this.stack[this.size() - 1]
}
isEmpty() {
return this.size() == 0
}
size() {
return this.stack.length
}
}
队列
队列和栈一样也是操作受限的线性结构,但和栈有所区别的是,队列可以在头部和尾部进行操作,但尾部只能插入,头部只能删除。这种受限的操作方式让队列元素的插入和删除遵循一种特殊的原则——先进先出原则(First In First Out,FIFO)。
JavaScript 在处理异步操作时经常会用到队列,比如宏任务队列、微任务队列、回调函数队列。
队列的实现也可以通过数组来实现,下面的代码实现了一个队列结构:
class Queue {
constructor(...args) {
// 使用数组进行模拟
this.queue = [...args]
}
enqueue(...items) {
// 入队
return this.queue.push(... items)
}
dequeue() {
// 出队
return this.queue.shift()
}
front() {
return this.isEmpty()
? undefined
: this.queue[0]
}
back() {
return this.isEmpty()
? undefined
: this.queue[this.size() - 1]
}
isEmpty() {
return this.size() == 0
}
size() {
return this.queue.length
}
}
最后说一句
如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下,您的支持是我坚持写作最大的动力,多谢支持。