2. 栈结构
2.1 概念
-
受限的线性结构,只能在顶部插入删除元素
-
LIFO(Last in first out) 后入先出
-
插入元素:进栈/入栈/压栈
-
删除元素:出栈/退栈
-
应用:函数的调用基于栈,第一个调用的函数放入栈底,嵌套最后调用的函数位于栈顶
-
例题:
有六个元素 6,5,4,3,2,1 的顺序进栈,下列不合法的出栈序列是 A.5 4 3 6 1 2 B.4 5 3 2 1 6 C.3 4 6 5 2 1 D.2 3 4 1 5 6 分析:看每个答案的第一个出栈元素,由此确定最开始进栈元素是哪些。不合法顺序一般就是这些第一批进栈元素的出栈顺序,因为后续的批次每个元素都可以立进立出,大概率顺序合法 答案:C 3先出 说明 6 5 4 3第一批入,6不可能比5先出
(())(((()())()))括号匹配 分析: 遍历 '('->进栈 ')'->栈顶元素出栈 从而做到每对括号一一匹配
2.2 封装与测试
-
JS没有Stack结构,需要自己封装一个类
-
实现方式:基于数组实现or基于链表实现,这里我们先基于数组封装
-
栈常见操作:
push(element)
pop()
peek()
isEmpty()
size()
toString()
-
封装:
//封装并导出 export class Stack { //es6创建类需要构造函数 constructor() { //定义一个数组变量用于保存当前栈对象中的所有元素 this.items = [] } //入栈 push(element) { this.items.push(element) } //出栈 pop() { this.items.pop() } //查看并返回栈顶元素 peek() { return this.items[this.items.length - 1] } //判断是否栈空 isEmpty() { return this.items.length === 0; } //返回栈元素个数 size() { return this.items.length } }
测试:
import {Stack} from "./stack" const stack = new Stack(); stack.push("abc"); stack.push("def"); stack.push("ghi"); stack.push("def"); console.log(stack.items); console.log(stack.pop()); console.log(stack.items); console.log(stack.peek()); console.log(stack.isEmpty()); console.log(stack.size());
2.3 应用
-
十进制转二进制
十进制数一直除以2取余数,倒着取得到的一串余数,就是十进制数的二进制表示。第一次取的余数压入栈底,依次压入所有余数。
export function dec2bin(num){ //1.创建栈 const stack = new Stack(); //2.循环取余数直至商为0 while(num>0){ let remainder =num%2; num = Math.floor(num/2);//向下取整 stack.push(remainder); } //3.反向拼接字符串 let binString = ""; while(!stack.isEmpty()){ binString+=stack.pop(); } return binString }
测试
import {Stack,dec2bin} from "./stack" console.log(dec2bin(100));
打印结果
1100100