Kazi Rahamatullah
Kazi Rahamatullah
AboutProjectsBlogContact
UsesBooks
ResumeView CV
Kazi Rahamatullah

© Copyright 2026 Kazi Rahamatullah

AboutProjectsBlogBooksUses
Twitter/XGitHubProduct HuntCodeSandbox
Back to Blog
DSAQueuesDequePriority Queue

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.

Jul 4, 20264 min read

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
1Type comparison
2Interactive visualizer
3Full implementation
4Choosing a type
5Real-life examples

1. Type comparison

TypeAccessDequeueTypical use
StandardFront/rearO(1)*General FIFO
CircularHead/tail wrapO(1)Fixed-size ring buffer
DequeBoth endsO(1)Sliding window, palindrome
PriorityHighest priorityO(log n)Scheduling, Dijkstra
LinkedHead/tail pointersO(1)True O(1) without shift

Back to index


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.

Circular buffer (capacity 6)
10
0
20
1
30
2
·
3
·
4
·
5
head → 0tail → 2

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.

Tip

Circular queues reuse slots — when tail reaches capacity, it wraps to index 0 if head has moved forward.

Back to index


3. Full implementation

js
// ── 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

js
// ── 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'

Back to index


4. Choosing a type

NeedPick
Fixed buffer, streaming IOCircular queue
Add/remove both endsDeque
Highest priority firstPriority queue (heap)
Avoid array shift costLinked queue

Interview Answer

"Why use a circular queue over a standard array queue?"

Standard array dequeue with shift is O(n). Circular queue moves head/tail pointers with modulo wrap — O(1) enqueue and dequeue in fixed memory.

Back to index


5. Real-life examples

TypeReal system
CircularAudio ring buffer, kernel pipe buffer
DequeBrowser history (back + forward), work-stealing deque
PriorityOS process scheduler, hospital triage
LinkedJob queue in Node.js libuv

Hospital triage priority queue

Emergency room — highest priority patient seen first, not arrival order.

P1routine (3)[0]
P2critical (1)[1]
P3urgent (2)[2]

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=routine

Full 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.

Back to index


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

Share this article

XLinkedInFacebook
Kazi Rahamatullah

Written by

Kazi Rahamatullah

FullStack Developer

X / TwitterGitHubLinkedIn

Subscribe to my newsletter

Stay up to date and get notified when I share new contents.

No spam ever, unsubscribe anytime