栈和队列

本文详细介绍了栈和队列这两种基本的数据结构,包括它们的特点(后进先出LIFO和先进先出FIFO),以及基于数组和链表的两种常见实现方式。通过实例演示了栈的push、pop、peek等操作,以及队列的enqueue、dequeue和front等。还重点讲解了优先级队列的应用,展示了如何在实际场景中利用这些数据结构优化问题解决。
摘要由CSDN通过智能技术生成
复习 栈和队列
栈和队列

前言:

我们知道数组是一种线性结构,并且可以在任意位置进行插入和删除,有时候为了实现某些功能,需要对这种任意性加以限制,而栈和队列就是比较常见的受限的线性表结构,

仅允许在表的一端进行插入和删除,这一端称为栈顶,另一端称为栈低。后进先出LIFO(last in first out):向一个栈插入元素叫做进栈,压栈,入栈,将新元素放到栈顶元素的上面,成为新的栈顶元素;从栈顶删除元素叫做出栈,退栈,删除栈顶元素,使其相邻的元素成为新的栈顶元素;

在这里插入图片描述

基于数组实现


function Stack() {
  this.data = [] // 用来存储栈中的数据

  // 向栈顶添加一个元素
  Stack.prototype.push = ele => {
    this.data.push(ele)
  }

  // 向栈顶删除一个元素,同时返回被移除的元素
  Stack.prototype.pop = () => {
    return this.data.pop()
  }

  // 返回栈顶元素
  Stack.prototype.peek = () => {
    return this.data[this.data.length - 1]
  }

  // 判断栈是否为空
  Stack.prototype.isEmpty = () => {
    return this.data.length === 0
  }

  // 返回栈里面的元素的个数
  Stack.prototype.size = () => {
    return this.data.length
  }

  // 将栈结构里面的内容以字符串形式返回
  Stack.prototype.toString = () => {
    return this.data.join('')
  }
}


基于链表实现

// 简易链表
function LinkedList() {
  this.head = null

  function Node(ele, next = null) {
    this.ele = ele
    this.next = next
  }

  this.length = 0

  //insert 在position位置前面插入节点
  LinkedList.prototype.insert = (position, ele) => {
    if (position < 0 || position > this.length) return
    const newNode = new Node(ele)
    const currentNode = this.head

    this.head = newNode
    newNode.next = currentNode

    this.length += 1
  }
  // removeAt 删除最前面的节点
  LinkedList.prototype.removeAt = () => {
    const currentNode = this.head
    this.head = currentNode.next
    this.length -= 1
    return currentNode
  }
//  转字符串
  LinkedList.prototype.toString = () => {
    let currentEle = this.head
    let str = ''
    while (currentEle) {
      str += currentEle.ele + '-'
      currentEle = currentEle.next
    }
    return str
  }
//  清空链表
  LinkedList.prototype.clear = () => {
    this.head = null
    this.length = 0
  }
}

function Stack() {
  this.data = new LinkedList()

//  入栈
  Stack.prototype.push = ele =>  this.data.insert(0, ele)

//  出栈
  Stack.prototype.pop = () => this.data.removeAt()
//  转字符串
  Stack.prototype.toString = () => this.data.toString()

  // 返回栈顶元素
  Stack.prototype.peek = () =>  this.data.head


  Stack.prototype.size = () => this.data.length

  Stack.prototype.isEmpty = () => this.data.length === 0

  Stack.prototype.clear = () => this.data.clear()
}

队列

在表的一端进行插入元素,这一端称为表的后端(rear),在表的另一端删除元素,这一端称为表的前端(front);先进先出 FIFO(first in first out)

在这里插入图片描述

基于数组实现


function Queue() {
  this.data = []

  Queue.prototype.enqueue = (ele) => {
    this.data.push(ele)
  }

  Queue.prototype.dequeue = () => {
    return this.data.shift()
  }

  Queue.prototype.front = () => {
    return this.data[0]
  }

  Queue.prototype.isEmpty = () => {
    return this.data.length === 0
  }

  Queue.prototype.size = () => {
    return this.data.length
  }

  Queue.prototype.toString = () => {
    return this.data.join('')
  }
}


基于链表实现

// 简易链表
function LinkedList() {
  this.head = null

  function Node(ele, next = null) {
    this.ele = ele
    this.next = next
  }

  this.length = 0
  //append 向列表末尾插入节点
  LinkedList.prototype.append = ele => {
    const newNode = new Node(ele)
    if (this.length === 0) {
      // 链表为空时直接插入
      this.head = newNode
      // newNode.next = null
    } else {
      // 链表不为空的时候插入到最后一个节点后面
      let currentNode = this.head
      // 遍历链表,找到最后一个节点
      while (currentNode.next) {
        currentNode = currentNode.next
      }
      currentNode.next = newNode
      newNode.next = null
    }
    // 让长度加一
    this.length += 1
  }
  // removeAt 删除最前面的节点
  LinkedList.prototype.removeAt = () => {
    const currentNode = this.head
    this.head = currentNode.next
    this.length -= 1
    return currentNode
  }

  //  转字符串
  LinkedList.prototype.toString = () => {
    let currentEle = this.head
    let str = ''
    while (currentEle) {
      str += currentEle.ele + '-'
      currentEle = currentEle.next
    }
    return str
  }

  //  清空链表
  LinkedList.prototype.clear = () => {
    this.head = null
    this.length = 0
  }
}

function Queue() {
  this.data = new LinkedList()

//  入队
  Queue.prototype.enqueue = ele => this.data.append(ele)

//  出队
  Queue.prototype.dequeue = () => this.data.removeAt()

//  转字符串
  Queue.prototype.toString = () => this.data.toString()

//  返回队列第一个元素
  Queue.prototype.front = () => this.data.head

  Queue.prototype.isEmpty = () => this.data.length === 0

  Queue.prototype.size = () => this.data.length

  Queue.prototype.clear = () => this.data.clear()
}

特殊的队列-----优先级队列

普通的队列插入一个元素会被放在表的后端,并且只有前面的数据处理完成后,才会处理当前数据,比如删除。当是优先级队列在插入元素的时候会考虑它的优先级,让当前元素的优先级与其他元素比较,比较完成后在插入到正确的位置

在这里插入图片描述


function PriorityQueue() {
  this.data = []
  function QueueElement(ele, priority) {
    this.element = ele
    this.priority = priority
  }
  // 改造插入方法,不再是普通插入,通过比较优先级之后在进行插入操作
  PriorityQueue.prototype.enqueue = (ele, priority) => {
    const currentEle = new QueueElement(ele, priority)
    // 如果队列为空,直接插入
    if (this.isEmpty()) {
      this.data.push(currentEle)
    } else {
      let right = this.size() - 1
      while (right >= 0 && currentEle.priority <= this.data[right].priority) {
        right--
      }
      right++
      this.data.splice(right, 0, currentEle)
    }
  }

  PriorityQueue.prototype.dequeue = () => {
    return this.data.shift()
  }

  PriorityQueue.prototype.front = () => {
    return this.data[0]
  }

  PriorityQueue.prototype.isEmpty = () => {
    return this.data.length === 0
  }

  PriorityQueue.prototype.size = () => {
    return this.data.length
  }

  PriorityQueue.prototype.toString = () => {
    return this.data.join('')
  }
}

const priority = new PriorityQueue()
priority.enqueue('p0', 0)
priority.enqueue('p3', 3)
priority.enqueue('p1', 1)
priority.enqueue('p4', 4)
priority.enqueue('p2', 2)
console.log(priority.data)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值