特点
链栈
栈的链接存储结构成为链栈,利用链表实现,链表中的每一个元素由两部分信息组成,一部分是存储其本身的信息(数据域),一部分是存储一个指示其直接后继的信息,即直接后继的存储位置(指针域)
对于链式栈,无栈满的问题,空间可以扩充,插入与删除仅在栈顶处执行,链式栈的栈顶在链头。
入栈操作:插入一个新元素node,只能在链接在栈顶处,指针域指向原栈顶元素(node.next = top;),栈顶指针top再指向这个新元素(top = node)
出栈操作:只能删除栈顶元素,删除时,栈顶指针指向原来栈顶元素的指针域。node = top; top = top.next; return node.data;
class Node {constructor(element) {this.element = element;this.next = null;}}/*** 属性:* length:栈的长度* top:栈顶指针** 方法:* push:入栈* pop:出栈* peek:读栈顶数据元素* toSting:遍历栈将每个节点值转换为字符串,并返回结果* isEmpty:判断栈是否为空* size:栈的数据元素个数* clear:清除栈数据*/class LinkStack {constructor() {this.length = 0;this.top = null; // 栈顶指针}push(element) {let curNode;let node = new Node(element);//如果栈顶是null则新元素节点直接作为栈顶if (!this.top) {this.top = node;} else {// 将新元素节点取代栈顶,并且指向的节点是原来栈顶元素节点curNode = this.top;node.next = curNode;this.top = node; // 插入的新元素为栈顶}this.length++;}pop() {let curNode = this.top;if (this.top === null) {return null;}let element = curNode.element;this.top = curNode.next; // 栈顶指针指向原来栈顶元素的指针域this.length--;return element;}peek() {if (this.top === null) {return null;}return this.top.element;}toString() {let str = "";let curNode = this.top;while (curNode) {str += curNode.element + ",";curNode = curNode.next;}str = str.slice(0, str.length - 1);return str;}isEmpty() {return this.top === null;}size() {return this.length;}clear() {this.top = null;this.length = 0;}}const linkStack = new LinkStack();let size = linkStack.size();console.log("size:", size);let isEmpty = linkStack.isEmpty();console.log("isEmpty:", isEmpty);let peek = linkStack.peek();console.log("读取栈顶:", peek);let pop = linkStack.pop();console.log(pop, "出栈");let toString = linkStack.toString();console.log("toString:", toString);linkStack.push("A");linkStack.push("B");linkStack.push("C");linkStack.push("D");toString = linkStack.toString();console.log("toString:", toString);pop = linkStack.pop();console.log(pop, "出栈");pop = linkStack.pop();console.log(pop, "出栈");pop = linkStack.pop();console.log(pop, "出栈");toString = linkStack.toString();console.log("toString:", toString);peek = linkStack.peek();console.log("读取栈顶:", peek);size = linkStack.size();console.log("size:", size);
顺序栈
栈,又叫堆栈,比列表高效,因为栈内的元素只能通过列表的一端访问,称为栈顶,数据只能在栈顶添加或删除,遵循先入后出(LIFO,last-in-first-out) 的原则,普遍运用于计算机的方方面面
顺序栈:利用一组地址连续的存储单元一次存放自栈底到栈顶的数据元素,把数组中下标为0的一端作为栈底对栈的操作主要有两种,一是将一个元素压入栈,push方法,另一个就是将栈顶元素出栈,pop方法。
/**属性:stackArray:存储栈数据方法:pop:出栈,删除栈顶元素,并且返回该值push:入栈,在栈顶将新元素入栈peek:查看当前栈顶元素,仅仅是查看,并不删除isEmpty:判断是否为空size:查看当前栈元素的总数clear:清空栈内元素toString:遍历栈查看所有元素*/class ArraySatck {constructor() {this.datas = [];}isEmpty() {return this.datas.length === 0;}size() {return this.datas.length;}push(item) {this.datas.push(item);}pop() {if (this.isEmpty()) {return null;}return this.datas.pop(); // 原生js数组pop方法删除最后一个元素并且返回}peek() {if (this.isEmpty()) {return null;}return this.datas[this.size() - 1];}clear() {this.datas = [];}toString() {return this.datas.toString();}}const arraySatck = new ArraySatck();let isEmp = arraySatck.isEmpty();console.log("是否为空", isEmp);length = arraySatck.size();console.log("栈长度", length);let pop = arraySatck.pop();console.log(pop + "出栈");let peek = arraySatck.peek();console.log("查看栈顶", peek);let str = arraySatck.toString();console.log("toSting", str);arraySatck.push("A");arraySatck.push("B");arraySatck.push("C");arraySatck.push("D");arraySatck.push("E");isEmp = arraySatck.isEmpty();console.log("是否为空", isEmp);length = arraySatck.size();console.log(length);pop = arraySatck.pop();console.log(pop + "出栈");pop = arraySatck.pop();console.log(pop + "出栈");peek = arraySatck.peek();console.log("查看栈顶", peek);str = arraySatck.toString();console.log("toSting", str);arraySatck.clear();str = arraySatck.toString();console.log("after clear toSting", str);let arr = arraySatck.datas;console.log("datas", arr);
