Queue Types — Circular, Deque, Priority & Linked Visualized
Compare queue implementations — circular buffer, deque, priority queue, linked queue with interactive visualizer, code, and real-world examples.
Introduction
Queue types extend basic FIFO with ring buffers, two-end access, and priority ordering. This guide covers circular, deque, priority, and linked queues — building on queue fundamentals.
Quick index
| # | Section |
|---|---|
| 1 | Type comparison |
| 2 | Interactive visualizer |
| 3 | Full implementation |
| 4 | Choosing a type |
| 5 | Real-life examples |
1. Type comparison
| Type | Access | Dequeue | Typical use |
|---|---|---|---|
| Standard | Front/rear | O(1)* | General FIFO |
| Circular | Head/tail wrap | O(1) | Fixed-size ring buffer |
| Deque | Both ends | O(1) | Sliding window, palindrome |
| Priority | Highest priority | O(log n) | Scheduling, Dijkstra |
| Linked | Head/tail pointers | O(1) | True O(1) without shift |
2. Interactive visualizer
Queue Types — Circular, Deque, Priority & Linked
Four queue variants — same FIFO concept extended for ring buffers, two-end access, and priority ordering.
Fixed-size ring buffer — head/tail wrap around. No shift on dequeue.
Circular queue
| class CircularQueue { | |
| constructor(cap) { this.buf = Array(cap); this.head = 0; this.tail = 0; this.size = 0 } | |
| enqueue(v) { this.buf[this.tail] = v; this.tail = (this.tail + 1) % this.cap; this.size++ } | |
| dequeue() { const v = this.buf[this.head]; this.head = (this.head + 1) % this.cap; this.size--; return v } | |
| } | |
| const cq = new CircularQueue(6) | |
| cq.enqueue(10); cq.enqueue(20); cq.enqueue(30) | → slots [0..2] filled |
Used in audio buffers, kernel ring buffers, streaming IO.
3. Full implementation
// ── Circular queue ──
class CircularQueue {
constructor(cap) {
this.buf = Array(cap)
this.head = 0
this.tail = 0
this.size = 0
this.cap = cap
}
enqueue(v) {
this.buf[this.tail] = v
this.tail = (this.tail + 1) % this.cap
this.size++
}
dequeue() {
const v = this.buf[this.head]
this.head = (this.head + 1) % this.cap
this.size--
return v
}
}
// ── Deque ──
class Deque {
constructor() {
this.items = []
}
pushFront(v) {
this.items.unshift(v)
}
pushBack(v) {
this.items.push(v)
}
popFront() {
return this.items.shift()
}
popBack() {
return this.items.pop()
}
}
// ── Linked queue ──
class QNode {
constructor(v) {
this.val = v
this.next = null
}
}
class LinkedQueue {
constructor() {
this.head = null
this.tail = null
}
enqueue(v) {
const n = new QNode(v)
if (!this.head) {
this.head = this.tail = n
return
}
this.tail.next = n
this.tail = n
}
dequeue() {
if (!this.head) return
const v = this.head.val
this.head = this.head.next
if (!this.head) this.tail = null
return v
}
}
// ── Min priority queue (simplified) ──
class MinPQ {
constructor() {
this.heap = []
}
enqueue(v) {
this.heap.push(v)
this._up(this.heap.length - 1)
}
dequeue() {
if (!this.heap.length) return
const min = this.heap[0]
const last = this.heap.pop()
if (this.heap.length) {
this.heap[0] = last
this._down(0)
}
return min
}
_up(i) {
/* bubble up */
}
_down(i) {
/* bubble down */
}
}Function calls with output
// ── Demo calls — output shown on the right ──
const cq = new CircularQueue(4)
cq.enqueue(1)
cq.enqueue(2)
cq.dequeue() // → 1
const d = new Deque()
d.pushBack(10)
d.pushFront(5) // → [5, 10]
d.popBack() // → 10
const lq = new LinkedQueue()
lq.enqueue('A')
lq.enqueue('B')
lq.dequeue() // → 'A'4. Choosing a type
| Need | Pick |
|---|---|
| Fixed buffer, streaming IO | Circular queue |
| Add/remove both ends | Deque |
| Highest priority first | Priority queue (heap) |
| Avoid array shift cost | Linked queue |
5. Real-life examples
| Type | Real system |
|---|---|
| Circular | Audio ring buffer, kernel pipe buffer |
| Deque | Browser history (back + forward), work-stealing deque |
| Priority | OS process scheduler, hospital triage |
| Linked | Job queue in Node.js libuv |
Hospital triage priority queue
Emergency room — highest priority patient seen first, not arrival order.
Arrival order ≠ treatment order.
Real-world implementation
class TriageQueue {
constructor() { this.heap = [] }
admit(patient) { /* insert by priority */ this.heap.push(patient); this._bubbleUp() }
treatNext() { /* extract highest priority */ return this._extractMax() }
}
// priority: 1=critical, 2=urgent, 3=routineFull working code for the scenario above.
Function calls with output
// ── Function calls with output ──
const triage = new TriageQueue()
triage.admit({ name:"P1", priority:3 })
triage.admit({ name:"P2", priority:1 })
triage.admit({ name:"P3", priority:2 })Side output shows return value after each call — step through to trace execution.
Summary
Circular for fixed buffers; deque for two-end access; priority for scheduling; linked for true O(1) without shift penalty.
Next reads: Queue Applications · DSA Queues
Subscribe to my newsletter
Stay up to date and get notified when I share new contents.
No spam ever, unsubscribe anytime