数据结构——队列

数据结构——队列

数据结构特点

队列是遵循先进先出(FIFO,也称为先来先服务)。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。

常见场景

  • 排队买票
  • 计算机中的打印队列。
  • JS中的任务队列

队列方法

  • enqueue(element(s)):向队列尾部添加一个(或多个)新的项
  • dequeue():移除队列的第一项(即排在队列最前面的项)并返回被移除的元素
  • peek():返回队列中第一个元素——最先被添加,也将是最先被移除的元素。队列不做任何变动(不移除元素,只返回元素信息——与Stack类的peek方法非常类似)。该方法在其他语言中也可以叫作front方法。
  • isEmpty():如果队列中不包含任何元素,返回true,否则返回false。
  • size():返回队列包含的元素个数,与数组的length属性类似

队列实现

// 队列,先进先出
class Queue {
  constructor() {
    // 记录队列尾的索引
    this.count = 0
    //用对象存放队列值
    this.items = {}
    //记录队列首的索引
    this.lowestCount = 0
  }
  // 队尾添加元素
  enqueue(ele) {
    this.items[this.count] = ele
    this.count++
  }

  dequeue() {
    if (this.isEmpty()) {
      return undefined
    }
    const res = this.items[this.lowestCount]
    delete this.items[this.lowestCount]
    this.lowestCount++
    return res
  }

  isEmpty() {
    return this.size() === 0
  }

  size(){
      return this.count - this.lowestCount
  }

  peek(){
      if(this.isEmpty()) return undefined
      return this.items[this.lowestCount]
  }

  clear(){
      this.items = {}
      this.count = 0
      this.lowestCount = 0
  }

  toString(){
      if(this.isEmpty()) return ''
      let objString = this.items[this.lowestCount]
      for(let i = this.lowestCount+1;i<this.count;i++){
          objString = `${objString},${this.items[i]}`
      }
      return objString
  }
}

let queue = new Queue()
console.log(queue.enqueue('a'))
console.log(queue.enqueue('b'))
console.log(queue.enqueue('c'))
console.log(queue.toString())
console.log(queue.dequeue())
console.log(queue.size())
console.log(queue.isEmpty())
console.log(queue.peek())
console.log(queue.clear())
console.log(queue.isEmpty())

//输出结果
undefined
undefined
undefined
a,b,c
a
2
false
b
undefined
true

数据结构——双端队列

数据结构特点

允许我们同时从前端和后端添加和移除元素的特殊队列。是结合了队列和栈的双重特点的队列。

常见场景

常见方法

  • addFront(element):该方法在双端队列前端添加新的元素。
  • addBack(element):该方法在双端队列后端添加新的元素(实现方法和Queue类中的enqueue方法相同)。
  • removeFront():该方法会从双端队列前端移除第一个元素(实现方法和Queue类中的dequeue方法相同)。
  • removeFront():该方法会从双端队列前端移除第一个元素(实现方法和Queue类中的dequeue方法相同)。
  • peekFront():该方法返回双端队列前端的第一个元素(实现方法和Queue类中的peek方法一样)。
  • peekBack():该方法返回双端队列后端的第一个元素(实现方法和Stack类中的peek方法一样)。

其他还包括isEmpty、clear、size、toString方法。

队列实现

// 双端队列,队手和队尾都可以增加删除
class Deque {
  constructor() {
    // 记录队列尾的索引
    this.count = 0
    //用对象存放队列值
    this.items = {}
    //记录队列首的索引
    this.lowestCount = 0
  }
  // 队尾添加元素,count永远指向下一个,注意peek的时候也需要注意count-1
  addBack(ele) {
    this.items[this.count] = ele
    this.count++
  }

  addFront(ele) {
    if (this.isEmpty()) {
      this.addBack(ele)
    } else if (this.lowestCount > 0) {
      this.lowestCount--
      this.items[this.lowestCount] = ele
    } else {
      for (let i = this.lowestCount; i < this.count; i++) {
        this.items[i + 1] = this.items[i]
      }
      this.count++
      this.items[this.lowestCount] = ele
    }
  }

  removeFront() {
    if (this.isEmpty()) {
      return undefined
    }
    const res = this.items[this.lowestCount]
    delete this.items[this.lowestCount]
    this.lowestCount++
    return res
  }

  removeBack() {
    if (this.isEmpty()) return undefined
    const res = this.items[this.count]
    delete this.items[this.count]
    this.count--
    return res
  }

  isEmpty() {
    return this.size() === 0
  }

  size() {
    return this.count - this.lowestCount
  }

  peekFront() {
    if (this.isEmpty()) return undefined
    return this.items[this.lowestCount]
  }
  //需要注意count是下一个
  peekBack() {
    if (this.isEmpty()) return undefined
    return this.items[this.count - 1]
  }

  clear() {
    this.items = {}
    this.count = 0
    this.lowestCount = 0
  }

  toString() {
    if (this.isEmpty()) return ""
    let objString = this.items[this.lowestCount]
    for (let i = this.lowestCount + 1; i < this.count; i++) {
      objString = `${objString},${this.items[i]}`
    }
    return objString
  }
}

const deque = new Deque()
console.log(deque.addFront("a"))
console.log(deque.peekFront())
console.log(deque.peekBack())
deque.addBack('b')
console.log(deque.toString())
console.log(deque.size())

//输出结果
undefined
a
a
a,b
2

常见面试题

1.击鼓传花

游戏规则:
在这个游戏中,孩子们围成一个圆圈,把花尽快地传递给旁边的人。某一时刻传花停止,这个时候花在谁手里,
谁就退出圆圈、结束游戏。重复这个过程,直到只剩一个孩子(胜者)
eleList:参与击鼓传花的名单
num 代表传递的次数
输出被删除的人和剩余的队列

function hotPhtato(eleList, num) {
  while (eleList.length > 1) {
    for (let i = 0; i < num; i++) {
      eleList.push(eleList.shift())
    }
    console.log(`${eleList.shift()}被淘汰`)
  }
  console.log(`${eleList.shift()}胜出`)
}

hotPhtato(["John", "Jack", "Camila", "Carl", "Ingrid"], 4)

输出结果

Ingrid被淘汰
John被淘汰
Camila被淘汰
Carl被淘汰
Jack胜出
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值