Skip to content

特点

后进先出(Last In First Out)

链栈

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

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

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

javascript
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方法。

javascript
/**
 属性:
 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)