【路飞】普通队列和循环队列

136 阅读1分钟

「这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

特点

  • 是一种线性的数据结构
  • 从一端(队首)添加元素,从另一端(队尾)删除元素
  • 先进先出

缺点

  • 入队的时间复杂度是 O(1)
  • 出队操作的时间复杂度是 O(n),性能太差

实现

class Queue {
  constructor() {
    this.dataStore = [];
  }
  // 入队
  enqueue(element) {
    this.dataStore.push(element);
  }
  // 出队
  dequeue() {
    return this.dataStore.shift();
  }
  // 队首
  front() {
    return this.dataStore[0];
  }
  // 队尾
  back() {
    return this.dataStore[this.dataStore.length - 1];
  }
  toString() {
    var retStr = "";
    for (var i = 0; i < this.dataStore.length; ++i) {
      retStr += this.dataStore[i] + "\n";
    }
    return retStr;
  }
  isEmpty() {
    return this.dataStore.length === 0;
  }
}

var q = new Queue();
for (var i = 0; i < 6; ++i) {
  q.enqueue(i);
}
q.dequeue();
console.log(q.toString());

性能优化

为了解决出队时,复杂度高O(n)的缺点(因为每一次出队,后面所有的元素都要往前挪动一位),就出现了循环队列。

循环队列:通过设置头尾指针来标记队列的头尾,而不是去删除队列中的元素,这样算法复杂度就降为了O(1);

题目:622. 设计循环队列

image.png

解答

/**
 * @param {number} k
 */
function MyCircularQueue(k) {
    this.dataStore = [];
    // 指向队列头部第 1 个有效数据的位置
    this.front = 0;
    // 下一个从队尾入队元素的位置
    this.tail = 0;
    // 标记队列的长度
    this.length = 0;
    // 初始化队列的容量
    this.capacity = k;
};

/** 
 * @param {number} value
 * @return {boolean}
 */
MyCircularQueue.prototype.enQueue = function(value) {
    if (this.length >= this.capacity) {
      return false;
    }
    this.dataStore[this.tail] = value;
    this.tail = (this.tail + 1) % this.capacity;
    this.length++;
    return true;
};

/**
 * @return {boolean}
 */
MyCircularQueue.prototype.deQueue = function() {
    if (this.length <= 0) {
      return false;
    }
    this.front = (this.front + 1) % this.capacity;
    this.length--;
    return true;
};

/**
 * @return {number}
 */
MyCircularQueue.prototype.Front = function() {
   if (this.length <= 0) {
      return -1;
    }
    return this.dataStore[this.front];
};

/**
 * @return {number}
 */
MyCircularQueue.prototype.Rear = function() {
    if (this.length <= 0) {
      return -1;
    }
    // 因为this.tail是指向下一个元素的,所以这里需要减一
    return this.dataStore[(this.tail + this.capacity - 1) % this.capacity];
};

/**
 * @return {boolean}
 */
MyCircularQueue.prototype.isEmpty = function() {
    return this.length === 0;
};

/**
 * @return {boolean}
 */
MyCircularQueue.prototype.isFull = function() {
   return this.length === this.capacity;
};