数组就不多说了,(js 中的数组内存是不连续的)
数组优缺点:
栈
数组是一种线性结构, 并且可以在数组的 任意位置 插入和删除数据
- 但是有时候, 为了实现某些功能, 必须对这种任意性 加以限制
- 栈和队列 就是比较常见的 受限的线性结构

站结构的实现
基于数组实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| export default class ArrayStack<T> { private data: T[] = []; push(element: T) { this.data.push(element); } pop(): T | undefined { return this.data.pop(); } peek(): T | undefined { return this.data[this.data.length - 1]; } isEmpty(): Boolean { return this.data.length === 0; } size(): number { return this.data.length; } }
const stack = new ArrayStack<string>(); stack.push("22"); stack.push("vv"); stack.push("abc");
|
基于链表实现
面试题 1 - 十进制转二进制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import Stack from "./stack重构";
function decimalToBinary(decimal: number): string { const stack = new Stack(); let remainder: number; let binary = ""; while (decimal > 0) { remainder = decimal % 2; stack.push(remainder); decimal = Math.floor(decimal / 2); } while (!stack.isEmpty()) { binary += stack.pop(); } return binary; }
console.log("---", decimalToBinary(35));
|
面试题 2 - 有效括号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import Stack from "./stack重构";
function isValid(s: string): Boolean { const stack = new Stack<string>(); const l = s.length; for (let i = 0; i < l; i++) { const val = s[i]; switch (val) { case "(": stack.push(")"); break; case "{": stack.push("}"); break; case "[": stack.push("]"); break; default: if (stack.pop() !== val) return false; break; } } return stack.isEmpty(); }
console.log(isValid("()")); console.log(isValid("(){}")); console.log(isValid("(){]")); console.log(isValid("(})")); console.log(isValid("({[]})"));
|
不足
上面用数组实现了栈,还可以用链表来实现栈,比如
1 2 3 4 5 6 7
| class LinkedStack { push() {} pop() {} peek() {} isEmpty() {} size() {} }
|
但是每次去实现栈都要记住对应的几个方法,这是个不足之处。
可是使用接口来完善
TS 中类可以继承类、类也可以实现接口
1 2 3 4 5 6 7
| interface iStack<T> { push: (element: T) => void; pop: () => T | undefined; peek: () => T | undefined; isEmpty: () => Boolean; size: () => number; }
|
这样就可以在定义类去实现这个接口
1 2 3 4 5 6 7
| class LinkedStack<T> implements IStack<T>{ push: (element: T) => void; pop: () => T | undefined; peek: () => T | undefined; isEmpty: () => Boolean; size: () => number; }
|
如果漏掉了接口里规定的,那么就会报错,不用再自己记忆有哪些方法属性要定义了
链表的实现等学习链表后再来做。