您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# JavaScript如何实现一个队列
## 队列基础概念
队列(Queue)是一种遵循**先进先出(FIFO)**原则的线性数据结构。与栈不同,队列允许在一端(队尾)添加元素,在另一端(队首)移除元素。这种特性使队列成为处理顺序任务的理想选择。
### 队列的核心操作
1. **enqueue(element)** - 向队尾添加元素
2. **dequeue()** - 移除队首元素
3. **peek()** - 查看队首元素(不移除)
4. **isEmpty()** - 检查队列是否为空
5. **size()** - 获取队列长度
## 数组实现队列
JavaScript数组天然支持队列操作,但存在性能问题:
```javascript
class ArrayQueue {
constructor() {
this.items = [];
}
enqueue(element) {
this.items.push(element); // O(1)
}
dequeue() {
return this.items.shift(); // O(n) - 性能瓶颈!
}
peek() {
return this.items[0];
}
isEmpty() {
return this.items.length === 0;
}
size() {
return this.items.length;
}
clear() {
this.items = [];
}
}
shift()
操作需要移动所有剩余元素,时间复杂度为O(n)通过维护头尾指针的优化实现:
class ObjectQueue {
constructor() {
this.items = {};
this.frontIndex = 0;
this.rearIndex = 0;
}
enqueue(element) {
this.items[this.rearIndex] = element;
this.rearIndex++;
}
dequeue() {
if (this.isEmpty()) return null;
const item = this.items[this.frontIndex];
delete this.items[this.frontIndex];
this.frontIndex++;
return item;
}
peek() {
return this.items[this.frontIndex];
}
isEmpty() {
return this.rearIndex - this.frontIndex === 0;
}
size() {
return this.rearIndex - this.frontIndex;
}
clear() {
this.items = {};
this.frontIndex = 0;
this.rearIndex = 0;
}
}
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
class LinkedListQueue {
constructor() {
this.head = null;
this.tail = null;
this.length = 0;
}
enqueue(value) {
const newNode = new Node(value);
if (!this.head) {
this.head = newNode;
this.tail = newNode;
} else {
this.tail.next = newNode;
this.tail = newNode;
}
this.length++;
}
dequeue() {
if (!this.head) return null;
const value = this.head.value;
this.head = this.head.next;
this.length--;
if (this.length === 0) {
this.tail = null;
}
return value;
}
// ...其他方法实现类似
}
解决普通队列的”假溢出”问题:
class CircularQueue {
constructor(k) {
this.size = k;
this.queue = new Array(k);
this.head = -1;
this.tail = -1;
}
enQueue(value) {
if (this.isFull()) return false;
if (this.isEmpty()) this.head = 0;
this.tail = (this.tail + 1) % this.size;
this.queue[this.tail] = value;
return true;
}
deQueue() {
if (this.isEmpty()) return false;
if (this.head === this.tail) {
this.head = -1;
this.tail = -1;
return true;
}
this.head = (this.head + 1) % this.size;
return true;
}
Front() {
return this.isEmpty() ? -1 : this.queue[this.head];
}
Rear() {
return this.isEmpty() ? -1 : this.queue[this.tail];
}
isEmpty() {
return this.head === -1;
}
isFull() {
return (this.tail + 1) % this.size === this.head;
}
}
class PriorityQueue {
constructor() {
this.items = [];
}
enqueue(element, priority) {
const queueElement = { element, priority };
let added = false;
for (let i = 0; i < this.items.length; i++) {
if (queueElement.priority < this.items[i].priority) {
this.items.splice(i, 0, queueElement);
added = true;
break;
}
}
if (!added) {
this.items.push(queueElement);
}
}
// 其他方法与普通队列相同
}
const taskQueue = new ObjectQueue();
function addTask(task) {
taskQueue.enqueue(task);
}
function processTasks() {
while (!taskQueue.isEmpty()) {
const task = taskQueue.dequeue();
try {
task.execute();
} catch (error) {
console.error('Task failed:', error);
}
}
}
function bfs(graph, startNode) {
const visited = new Set();
const queue = new LinkedListQueue();
queue.enqueue(startNode);
while (!queue.isEmpty()) {
const currentNode = queue.dequeue();
if (!visited.has(currentNode)) {
console.log('Visiting:', currentNode);
visited.add(currentNode);
for (const neighbor of graph[currentNode]) {
queue.enqueue(neighbor);
}
}
}
}
class MessageQueue {
constructor() {
this.queue = new ObjectQueue();
this.subscribers = new Set();
}
publish(message) {
this.queue.enqueue(message);
this.notifySubscribers();
}
subscribe(callback) {
this.subscribers.add(callback);
}
notifySubscribers() {
while (!this.queue.isEmpty()) {
const message = this.queue.dequeue();
this.subscribers.forEach(sub => sub(message));
}
}
}
// 测试10,000次操作
function testPerformance(QueueClass) {
const queue = new QueueClass();
const start = performance.now();
for (let i = 0; i < 10000; i++) {
queue.enqueue(i);
}
for (let i = 0; i < 10000; i++) {
queue.dequeue();
}
return performance.now() - start;
}
console.log('ArrayQueue:', testPerformance(ArrayQueue), 'ms');
console.log('ObjectQueue:', testPerformance(ObjectQueue), 'ms');
console.log('LinkedListQueue:', testPerformance(LinkedListQueue), 'ms');
class GenericQueue<T> {
private items: T[] = [];
enqueue(item: T): void {
this.items.push(item);
}
dequeue(): T | undefined {
return this.items.shift();
}
}
JavaScript实现队列有多种方式,各有优缺点。理解不同实现方式的特性,才能在实际开发中选择最适合的方案。对于大多数生产环境,推荐使用对象或链表实现以获得最佳性能,而数组实现则适合快速原型开发和小规模数据处理。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。