কম্পিউটার টিউটোরিয়াল

জাভাস্ক্রিপ্টে ডাবলি লিংকড লিস্টকে সার্কুলার (Circular) করা


Doubly Circular Linked List: কনসেপ্ট ও ইমপ্লিমেন্টেশন নোটস

Doubly Circular Linked List-এ লিস্টের শেষ নোডের next প্রথম নোডকে (হেড) পয়েন্ট করে, এবং প্রথম নোডের prev শেষ নোডকে (টেইল) পয়েন্ট করে। এটি উভয় দিকেই সার্কুলার হয়।

স্ট্রাকচার ভিজ্যুয়াল

HEAD (Node 1)                                    TAIL (Node N)
  ↑                                                  ↓
  │                                                  │
  └────────────── prev ──────────────────────────────┘
  
  Node 1 ⇄ Node 2 ⇄ Node 3 ⇄ ... ⇄ Node N
   ↑                                      ↓
   └────────────── next ──────────────────┘

মূল বৈশিষ্ট্য

  • No Null Pointers: কোনো নোডের next বা prev null নয়।
  • Continuous Traversal: যেকোনো নোড থেকে শুরু করে পুরো লিস্ট ট্রাভার্স করা যায়।
  • Head/Tail Arbitrary: হেড/টেইল লজিক্যাল কনসেপ্ট, ফিজিক্যালি কোনো নোড হতে পারে।

ইনসারশন/ডিলিশন নোটস

অপারেশনগুলো রেগুলার ডাবলি লিংকড লিস্টের মতোই, শুধু সার্কুলার লিংক মেনটেইন রাখতে হয়:

ইনসারশন (Insert at End/Append)

append(data) {
  const node = new Node(data);
  
  if (!this.head) {
    // Empty List: Self-loop
    node.next = node;
    node.prev = node;
    this.head = node;
    this.tail = node;
  } else {
    // Insert after Tail (Before Head)
    node.prev = this.tail;
    node.next = this.head;
    this.tail.next = node;
    this.head.prev = node;
    this.tail = node;
  }
  this.length++;
}

ডিলিশন (Delete Node)

remove(node) {
  if (!this.head) return;
  
  if (this.head === this.tail && this.head === node) {
    // Only One Node
    this.head = null;
    this.tail = null;
  } else if (node === this.head) {
    // Remove Head
    this.head = node.next;
    this.head.prev = this.tail;
    this.tail.next = this.head;
  } else if (node === this.tail) {
    // Remove Tail
    this.tail = node.prev;
    this.tail.next = this.head;
    this.head.prev = this.tail;
  } else {
    // Remove Middle
    node.prev.next = node.next;
    node.next.prev = node.prev;
  }
  this.length--;
}

ট্রাভার্সাল (Avoiding Infinite Loop)

// Forward Traversal
displayForward() {
  if (!this.head) return;
  let curr = this.head;
  do {
    console.log(curr.data);
    curr = curr.next;
  } while (curr !== this.head); // Stop Condition: Back to Head
}

// Backward Traversal
displayBackward() {
  if (!this.tail) return;
  let curr = this.tail;
  do {
    console.log(curr.data);
    curr = curr.prev;
  } while (curr !== this.tail);
}

বাস্তব ব্যবহার (Use Cases)

  • Round-Robin Scheduling: CPU টাস্ক শিডিউলিং, লোড ব্যালেন্সার।
  • Music/Video Playlist: Auto-repeat, Next/Previous Navigation।
  • Game Turn System: Multiplayer গেমে প্লেয়ার টার্ন রোটেশন।
  • Buffer/Ring Buffer: ফিক্সড সাইজ সার্কুলার বাফার।
  • Undo/Redo with History Limit: পুরানো স্টেট আটোমেটিকালি ওভাররাইট।

সতর্কতা

  • while (curr !== null) ব্যবহার করলে ইনফিনিট লুপ হবে — শর্ত হবে curr !== startNode।
  • গারবেজ কলেকশন: নোড রিমুভ করার পর node.next = node.prev = null করলে GC ফাস্ট হবে।
  1. জাভাস্ক্রিপ্টে লিংকড লিস্ট রিপ্রেজেন্টেশন (Visual)

  2. জাভাস্ক্রিপ্টে সিংলি লিংকড লিস্টকে সার্কুলার (Circular) করা

  3. সি++-এ ডাবলি লিংকড সার্কুলার লিস্ট

  4. C++-এ সার্কুলার লিঙ্কড লিস্টে নোড গণনা