数据结构与算法 javascript描述-队列

531 阅读2分钟

图解队列结构

队列

栈 VS 队列

所以,队列跟栈一样,也是一种操作受限的线性表数据结构。

常见的使用队列的场景

队列这个概念非常好理解。你可以把它想象成排队买票,先来的先买,后来的人只能站末尾,不允许插队。先进者先出,这就是典型的“队列”。

队列的概念很好理解,基本操作也很容易掌握。作为一种非常基础的数据结构,队列的应用也非常广泛,特别是一些具有某些额外特性的队列,比如循环队列、阻塞队列、并发队列。它们在很多偏底层系统、框架、中间件的开发中,起着关键性的作用。

跟栈一样,队列可以用数组来实现,也可以用链表来实现。用数组实现的栈叫作顺序栈,用链表实现的栈叫作链式栈。同样,用数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列。

顺序队列

顺序队列

链式队列

链式队列

循环队列

循环队列

阻塞队列

阻塞队列

常见的队列操作

队列操作

方法实现

JS通过数组实现一个队列结构

数组实现一个队列结构

入队操作

出队操作


const assert = require('assert')

class Queue {
  constructor(items = []) {
    this.items = items
  }
  enqueue(item) {
    return this.items.push(item)
  }
  dequeue() {
    return this.items.shift()
  }
  front() {
    return this.items[0]
  }
  size() {
    return this.items.length
  }
  isEmpty() {
    return this.items.length === 0
  }
}


const q = new Queue()
q.enqueue(1)
q.enqueue(2)
assert.strictEqual(q.front(), 1)
assert.strictEqual(q.size(), 2)
assert.strictEqual(q.dequeue(), 1)
q.dequeue()
assert.ok(q.isEmpty())

实例演示

循环队列-击鼓传花

击鼓传花
假设花每传递3次,花在谁手上,谁就被踢出队伍。

击鼓传花demo

其实这里使用到了循环队列,谁拿到花就先出队列然后跑到队列尾部入队,如果刚刚好等于3则直接踢出队列。


const assert = require('assert')

class Queue {
  constructor(items = []) {
    this.items = items
  }
  enqueue(item) {
    return this.items.push(item)
  }
  dequeue() {
    return this.items.shift()
  }
  front() {
    return this.items[0]
  }
  size() {
    return this.items.length
  }
  isEmpty() {
    return this.items.length === 0
  }
}



function passFlower(items = [], loop) {
  const q = new Queue(items)
  let count = 1
  while (q.size() > 1) {
    if (count === loop) {
      q.dequeue()
      count = 1
    } else {
      q.enqueue(q.dequeue())
      count += 1
    }
  }
  return q.front()
}

assert.strictEqual(passFlower(['a', 'b', 'c', 'd', 'e', 'f'], 3), 'a')

优先队列


const assert = require('assert')


// 元素类
class QueueItem {
  constructor(element, priority) {
    this.element = element
    this.priority = priority
  }
}

// 优先队列类
class PriorityQueue {
  constructor(items = []) {
    this.items = items
  }
  enqueue(element, priority) {
    const item = new QueueItem(element, priority)
    let isSuccessInsert = false
    // 此demo默认优先级高的排在前面
    for(let i = 0; i < this.items.length; i++) {
      if(item.priority > this.items[i].priority) {
        this.items.splice(i, 0, item)
        isSuccessInsert = true
        break
      }
    }
    // 优先级最低
    !isSuccessInsert && (this.items.push(item))
  }
  dequeue() {
    return this.items.shift()
  }
  front() {
    return this.items[0]
  }
  size() {
    return this.items.length
  }
  isEmpty() {
    return this.items.length === 0
  }
}


// testing

const q = new PriorityQueue()
q.enqueue('小红', 12)
q.enqueue('小明', 5)
q.enqueue('小红', 7)
assert.strictEqual(q.size(), 3)
assert.strictEqual(q.front().element, '小红')
q.dequeue()
q.dequeue()
assert.strictEqual(q.front().element, '小明')

PS: 感兴趣的可以关注下我的公众号。