栈
栈可以看成是一种受限的线性结构(所谓线性结构这里指的是数组)
相关概念
栈顶:允许数据进出的唯一出口
栈底:相对于栈顶的另一端
进栈:把新元素放在栈顶
出栈:把栈顶的元素取出
特点
- 后进先出(LIFO):指的是最后进入的元素第一个弹出栈空间
- 次序不变:栈中的各个数据之间的相对位置是不允许发生变化的
常见使用场景
函数调用
函数A调用函数B-函数B调用函数C-函数C调用函数D-函数D调用函数F;
等到F执行完毕之后以F-D-C-B-A的顺序弹出;由于F是最后调用却是最先弹出的,所以符合栈结构。
栈的实现
- 基于数组实现栈结构
- 基于链表实现栈结构(待补充)
栈方法
- push: 新元素入栈
- pop: 栈顶元素弹出
- peek: 返回栈顶元素但不弹出
- isEmpty: 检查栈是否为空
- size: 返回栈大小(栈元素个数)
- toString: 打印栈中元素
typescript实现(javascript代码见代码块)
class Stack<Element> {
items:Element[] = [];
// 入栈
push(element: Element){
this.items.push(element);
}
// 出栈
pop(): Element | null{
return this.isEmpty() ? null : this.items.pop()!;
}
// 返回栈顶
peek(): Element | null{
return this.isEmpty() ? null :this.items[this.size() - 1];
}
// 是否为空
isEmpty(): boolean{
return !!this.size();
}
// 栈大小
size(): number{
return this.items.length;
}
// 打印栈中元素
toString(join:string): string{
return this.items.join(join);
}
}
const s = new Stack<number>();
s.push(1);
s.push(9);
s.push(9);
s.push(5);
console.log(s.toString('>>>')); // 1>>>9>>>9>>>5
应用
应用一:进制转换
要求:使用栈数据结构写一个函数实现十进制向二进制的转换
function toBin(num: number) {
let leftNumber = num;
const stack = new Stack();
// core start ...
while(leftNumber > 0){
stack.push(leftNumber % 2);
leftNumber = Math.floor(leftNumber / 2);
}
// core finish ...
const join = '<<<';
const rawRst = stack.toString(join);
return rawRst.split(join).reverse().join("");
}
console.log(toBin(101)); // 1100101