特点

后进先出(Last In First Out)

链栈

栈的链接存储结构成为链栈,利用链表实现,链表中的每一个元素由两部分信息组成,一部分是存储其本身的信息(数据域),一部分是存储一个指示其直接后继的信息,即直接后继的存储位置(指针域)

对于链式栈,无栈满的问题,空间可以扩充,插入与删除仅在栈顶处执行,链式栈的栈顶在链头。

入栈操作:插入一个新元素node,只能在链接在栈顶处,指针域指向原栈顶元素(node.next = top;),栈顶指针top再指向这个新元素(top = node)
出栈操作:只能删除栈顶元素,删除时,栈顶指针指向原来栈顶元素的指针域。node = top; top = top.next; return node.data;

  1. class Node {
  2. constructor(element) {
  3. this.element = element;
  4. this.next = null;
  5. }
  6. }
  7. /**
  8. * 属性:
  9. * length:栈的长度
  10. * top:栈顶指针
  11. *
  12. * 方法:
  13. * push:入栈
  14. * pop:出栈
  15. * peek:读栈顶数据元素
  16. * toSting:遍历栈将每个节点值转换为字符串,并返回结果
  17. * isEmpty:判断栈是否为空
  18. * size:栈的数据元素个数
  19. * clear:清除栈数据
  20. */
  21. class LinkStack {
  22. constructor() {
  23. this.length = 0;
  24. this.top = null; // 栈顶指针
  25. }
  26. push(element) {
  27. let curNode;
  28. let node = new Node(element);
  29. //如果栈顶是null则新元素节点直接作为栈顶
  30. if (!this.top) {
  31. this.top = node;
  32. } else {
  33. // 将新元素节点取代栈顶,并且指向的节点是原来栈顶元素节点
  34. curNode = this.top;
  35. node.next = curNode;
  36. this.top = node; // 插入的新元素为栈顶
  37. }
  38. this.length++;
  39. }
  40. pop() {
  41. let curNode = this.top;
  42. if (this.top === null) {
  43. return null;
  44. }
  45. let element = curNode.element;
  46. this.top = curNode.next; // 栈顶指针指向原来栈顶元素的指针域
  47. this.length--;
  48. return element;
  49. }
  50. peek() {
  51. if (this.top === null) {
  52. return null;
  53. }
  54. return this.top.element;
  55. }
  56. toString() {
  57. let str = "";
  58. let curNode = this.top;
  59. while (curNode) {
  60. str += curNode.element + ",";
  61. curNode = curNode.next;
  62. }
  63. str = str.slice(0, str.length - 1);
  64. return str;
  65. }
  66. isEmpty() {
  67. return this.top === null;
  68. }
  69. size() {
  70. return this.length;
  71. }
  72. clear() {
  73. this.top = null;
  74. this.length = 0;
  75. }
  76. }
  77. const linkStack = new LinkStack();
  78. let size = linkStack.size();
  79. console.log("size:", size);
  80. let isEmpty = linkStack.isEmpty();
  81. console.log("isEmpty:", isEmpty);
  82. let peek = linkStack.peek();
  83. console.log("读取栈顶:", peek);
  84. let pop = linkStack.pop();
  85. console.log(pop, "出栈");
  86. let toString = linkStack.toString();
  87. console.log("toString:", toString);
  88. linkStack.push("A");
  89. linkStack.push("B");
  90. linkStack.push("C");
  91. linkStack.push("D");
  92. toString = linkStack.toString();
  93. console.log("toString:", toString);
  94. pop = linkStack.pop();
  95. console.log(pop, "出栈");
  96. pop = linkStack.pop();
  97. console.log(pop, "出栈");
  98. pop = linkStack.pop();
  99. console.log(pop, "出栈");
  100. toString = linkStack.toString();
  101. console.log("toString:", toString);
  102. peek = linkStack.peek();
  103. console.log("读取栈顶:", peek);
  104. size = linkStack.size();
  105. console.log("size:", size);

顺序栈

栈,又叫堆栈,比列表高效,因为栈内的元素只能通过列表的一端访问,称为栈顶,数据只能在栈顶添加或删除,遵循先入后出(LIFO,last-in-first-out) 的原则,普遍运用于计算机的方方面面

顺序栈:利用一组地址连续的存储单元一次存放自栈底到栈顶的数据元素,把数组中下标为0的一端作为栈底对栈的操作主要有两种,一是将一个元素压入栈,push方法,另一个就是将栈顶元素出栈,pop方法。

  1. /**
  2. 属性:
  3. stackArray:存储栈数据
  4. 方法:
  5. pop:出栈,删除栈顶元素,并且返回该值
  6. push:入栈,在栈顶将新元素入栈
  7. peek:查看当前栈顶元素,仅仅是查看,并不删除
  8. isEmpty:判断是否为空
  9. size:查看当前栈元素的总数
  10. clear:清空栈内元素
  11. toString:遍历栈查看所有元素
  12. */
  13. class ArraySatck {
  14. constructor() {
  15. this.datas = [];
  16. }
  17. isEmpty() {
  18. return this.datas.length === 0;
  19. }
  20. size() {
  21. return this.datas.length;
  22. }
  23. push(item) {
  24. this.datas.push(item);
  25. }
  26. pop() {
  27. if (this.isEmpty()) {
  28. return null;
  29. }
  30. return this.datas.pop(); // 原生js数组pop方法删除最后一个元素并且返回
  31. }
  32. peek() {
  33. if (this.isEmpty()) {
  34. return null;
  35. }
  36. return this.datas[this.size() - 1];
  37. }
  38. clear() {
  39. this.datas = [];
  40. }
  41. toString() {
  42. return this.datas.toString();
  43. }
  44. }
  45. const arraySatck = new ArraySatck();
  46. let isEmp = arraySatck.isEmpty();
  47. console.log("是否为空", isEmp);
  48. length = arraySatck.size();
  49. console.log("栈长度", length);
  50. let pop = arraySatck.pop();
  51. console.log(pop + "出栈");
  52. let peek = arraySatck.peek();
  53. console.log("查看栈顶", peek);
  54. let str = arraySatck.toString();
  55. console.log("toSting", str);
  56. arraySatck.push("A");
  57. arraySatck.push("B");
  58. arraySatck.push("C");
  59. arraySatck.push("D");
  60. arraySatck.push("E");
  61. isEmp = arraySatck.isEmpty();
  62. console.log("是否为空", isEmp);
  63. length = arraySatck.size();
  64. console.log(length);
  65. pop = arraySatck.pop();
  66. console.log(pop + "出栈");
  67. pop = arraySatck.pop();
  68. console.log(pop + "出栈");
  69. peek = arraySatck.peek();
  70. console.log("查看栈顶", peek);
  71. str = arraySatck.toString();
  72. console.log("toSting", str);
  73. arraySatck.clear();
  74. str = arraySatck.toString();
  75. console.log("after clear toSting", str);
  76. let arr = arraySatck.datas;
  77. console.log("datas", arr);