数据结构-队列篇

135 阅读1分钟

队列

队列是遵循先进先出的有序集合,在队列尾部添加新元素,队列首部移除元素,最新添加的元素加在队列尾部

Queue


  // 对象模拟
  class Queue {
    item = {}

    count = 0

    lastIndex = 0

    enqueue(value) {
      this.item[this.count] = value
      this.count++
    }

    dequeue() {
      if (this.isEmpty()) {
        return undefined
      }

      const result = this.item[this.lastIndex]
      delete this.item[this.lastIndex]
      this.lastIndex++

      return result
    }

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

    isEmpty() {
      return this.lastIndex === this.count
    }

    print() {
      let str = this.item[0]

      for (let i = 1; i < this.count; i++) {
        str = `${str}=>${this.item[i]}`
      }

      return str
    }

    clear() {
      this.item = {}
      this.count = 0
      this.lastIndex = 0
    }
  }


    // 数组模拟
    class Queue {
        item = []

        enqueue(value) {
        this.item.push(value)
        }

        dequeue() {
        return this.item.shift()
        }

        size() {
        return this.item.length
        }

        isEmpty() {
        return this.item.length === 0
        }

        print() {
        return this.item.join('=>')
        }

        clear() {
        this.item = []
        }
    }

双端队列


   class DoubleQueue {
    item = {}

    count = 0

    lastIndex = 0

    //  需要判断头索引是否为0
    addFront(value) {
      if (this.isEmpty()) {
        this.addBack()
      }

      if (this.lastIndex === 0) {
        for (let i = this.count; i > 0; i--) {
          this.item[i] = this.item[i - 1]
        }

        this.item[0] = value
        this.count++
      } else {
        this.lastIndex--
        this.item[this.lastIndex] = value
      }
    }

    addBack(value) {
      this.item[this.count] = value
      this.count++
    }

    removeBack() {
      if (this.isEmpty()) {
        return undefined
      }

      this.count--
      const result = this.item[this.count]
      delete this.item[this.count]
      return result
    }

    removeFront() {
      if (this.isEmpty()) {
        return undefined
      }

      const result = this.item[this.lastIndex]
      delete this.item[this.lastIndex]
      this.lastIndex++

      return result
    }

    peekFront() {
      return this.item[this.lastIndex]
    }

    peekBack() {
      return this.item[this.count - 1]
    }

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

    isEmpty() {
      return this.lastIndex === this.count
    }

    print() {
      let str = this.item[0]

      for (let i = 1; i < this.count; i++) {
        str = `${str}=>${this.item[i]}`
      }

      return str
    }

    clear() {
      this.item = {}
      this.count = 0
      this.lastIndex = 0
    }
  }
  

示例

循环队-击鼓传花问题

0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字(删除后从下一个数字开始计数)。求出这个圆圈里剩下的最后一个数字。
例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。

输入: n = 5, m = 3 输出: 3


    // 用数组
    const fn = (arr: string[], dep: number) => {
        const weedOutList = []
        const queque = new DoubleQueue()

        while (arr.length > 1) {
            for (let i = 0; i < dep; i++) {
                arr.push(arr.shift())
            }

            weedOutList.push(arr.shift())
        }

        return {
            winnner: arr,
            weedOutList,
        }
    }


    // 用循环队列
    const fn = (arr: string[], dep: number) => {
        const weedOutList = []
        const queque = new DoubleQueue()

        for (let i = 0; i < arr.length; i++) {
            queque.addBack(arr[i])
        }

        while (queque.size() > 1) {
            for (let i = 0; i < dep; i++) {
                // 出栈入栈
                queque.addBack(queque.removeFront())
            }

            const res = queque.removeFront()
            console.log(res)
            weedOutList.push(res)
        }

        return {
            winnner: queque.item,
            weedOutList,
        }
    }

回文检查器

回文是正反都能读通的单词、词组、数或一系列字符的序列,例如 madam或 racecar。


  const fn = (str: string = '') => {
    if (!str) {
      return false
    }

    let isEqual = true
    const queque = new DoubleQueue()

    for (let i = 0; i < str.length; i++) {
      queque.addBack(str.charCodeAt(i))
    }

    while ((queque.size() > 1) & isEqual) {
      const first = queque.removeFront()
      const last = queque.removeBack()

      if (first !== last) {
        isEqual = false
      }
    }

    return isEqual
  }