【TS数据结构】栈
栈
栈是一种先进先出(LIFO)原则的有序集合。新添加或待删除的元素都处于栈的同一端,称作栈顶,另一端叫做栈底。在栈里,新元素都靠近栈顶,旧元素都靠近栈底。
栈的一些方法:
- push(element[s]):添加一个(或多个)新元素到栈顶
- pop():从栈顶弹出一个元素
- peek():看一下栈顶的元素,但是不弹出
- isEmpty():返回栈是否为空
- clear():清除栈中所有的元素
- size():返回栈中的元素的个数
创建一个基于数组的栈
class ArrayStack<T> {
private _array: T[]
constructor() {
this._array = []
}
push(...elements: T[]): void {
this._array.push(...elements)
}
pop(): T {
return this._array.pop()
}
peek(): T {
let len = this._array.length
return this._array[len - 1]
}
isEmpty(): boolean {
return this._array.length <= 0
}
clear(): void {
this._array.length = 0
}
size(): number {
return this._array.length
}
}
export default ArrayStack
这里我们用了一个数组来模拟栈,利用数组身上的push()和pop()可以很轻易地实现栈这种数据结构的一些操作。
在ArrayStack地内部有一个私有的_array属性,存放的是T类型(泛型)的数组。这是使用的是_命名规范也就是js中私有变量的命名规范,我们也可以省略前面的_因为我们用的是ts可以直接声明私有属性。
使用数组的API创建一个栈是最简单的。但是在处理大量数据的时候,我们同样需要评估如何操作数据是最搞笑的。在创建数组时,大部分方法的时间复杂度是$O(n)$。$O(n)$的意思是,我们需要迭代整个数组知道找到要找的那个元素,在最坏的情况下需要迭代数组所有的位置。
如果我们能够直接获取元素,占用较少的内存空间,并且荏苒保证所有元素按照我们的需要排列,不是更好吗?对于js语言实现栈数据结构的场景,我们也可以使用一个js对象来存储所有栈元素,保证他们的顺序并且遵守LIFO原则。
使用一个对象来实现栈
class Stack<T> {
private items: {}
private count: number
constructor() {
this.items = {}
this.count = 0
}
push(element: T) {
this.items[this.count++] = element
}
pop(): T {
if (this.isEmpty()) return undefined
this.count--
const res = this.items[this.count]
delete this.items[this.count]
return res
}
peek(): T {
if (this.isEmpty()) return undefined
return this.items[this.count - 1]
}
isEmpty(): boolean {
return this.count <= 0
}
clear(): void {
this.items = {}
this.count = 0
}
toString() {
if (this.isEmpty()) return 'stack is empty!'
let res = this.items[0].toString()
for (let i = 1; i < this.count; i++) {
res = `${res}, ${this.items[i].toString()}`
}
return res
}
}
export default Stack
使用对象来模拟栈,可以解决数组中的方法都需要便利数组的情况,理论上来说是要比数组实现的栈效率更高
用栈解决问题
栈的实际应用非常广泛。在回溯问题中,他可存储访问过的任务或路径、撤销的操作。
从十进制转到二进制
要把十进制转换成二进制,我们可以将该十进制数除2并对商取整,知道结果为0为止。举个例子,把十进制数10转化成二进制的数字,大致的过程是如下这样的。

import Stack from '../../ds/stack'
export const decimalToBinary = (decimal: number): string => {
const stack = new Stack<string>()
let n: number = decimal
let binaryStr: string = ''
while (n > 0) {
stack.push((n % 2) + '')
n = Math.floor(n / 2)
}
while (!stack.isEmpty()) {
binaryStr += stack.pop()
}
return binaryStr
}
ts数据结构仓库地址: https://github.com/FarajMujey/dsa.ts

浙公网安备 33010602011771号