WEEK 2 • هياكل البيانات

Linked List

القوائم المتصلة

إيه هي الـ Linked List؟

🔗 الفكرة الأساسية

📖 تشبيه القطار

تخيل قطار - كل عربية فيها:

  • البيانات (الركاب)
  • وصلة للعربية اللي بعدها (pointer/reference)

آخر عربية (last node) بتشاور على null - مفيش حاجة بعدها!

💡 الفرق الكبير عن الـ Array

في الـ Array، العناصر ورا بعض في الذاكرة (contiguous).

في الـ Linked List، العناصر متفرقة في الذاكرة!
بس كل واحد عارف مكان اللي بعده.

🧩 تركيبة الـ Node

Data

Data: القيمة المخزنة
Next: مؤشر (pointer) للـ node التالي

Linked List Structure

HEAD →
10
25
33
47
null

كل node بتشاور على اللي بعدها، وآخر واحدة بتشاور على null

Array vs Linked List

المقارنة Array Linked List
الذاكرة متتالية (Contiguous) متفرقة (Scattered)
Access بالـ Index O(1) ✓ O(n) ✗
Insert في الأول O(n) O(1) ✓
Delete من الأول O(n) O(1) ✓
استهلاك الذاكرة أقل أكتر (pointer لكل node)
الحجم ثابت (في بعض اللغات) متغير (Dynamic)

🎯 امتى تستخدم Array؟

  • • لما تحتاج توصل للعناصر بالـ index كتير
  • • لما تعرف الحجم من البداية
  • • لما الذاكرة مهمة

🎯 امتى تستخدم Linked List؟

  • • لما تضيف/تحذف من الأول كتير
  • • لما الحجم متغير
  • • لما مش محتاج access بالـ index

العمليات بالتفصيل

INSERT HEAD إضافة في الأول O(1)

📝 الخطوات:

1. اعمل node جديد بالقيمة
2. خلي الـ next بتاع الـ node الجديد يشاور على الـ head الحالي
3. حدث الـ head يشاور على الـ node الجديد

💡 ليه O(1)؟

مش محتاجين نعدي على أي node تانية - بنتعامل مع الـ head مباشرة!

مثال: إضافة 5 في الأول

Before:

HEAD →
10
25

After:

HEAD →
5
10
25
DELETE HEAD حذف من الأول O(1)

📝 الخطوات:

1. خلي الـ head يشاور على الـ node التانية (head.next)
2. الـ node الأولى هتتمسح من الذاكرة (Garbage Collection)

مثال: حذف أول عنصر

Before:

HEAD →
10
25
33

After:

HEAD →
25
33
TRAVERSE التنقل / البحث O(n)

عشان توصل لعنصر معين، لازم تبدأ من الـ head وتمشي node بـ node لحد ما توصل!

⚠️ مفيش random access زي الـ Array - ده العيب الكبير!

INTERACTIVE

Try It Yourself!

Enter a value and click an operation.

Implementation

LinkedList.js
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

class LinkedList {
  constructor() {
    this.head = null;
  }
  
  // O(1) - Add to head
  prepend(value) {
    const node = new Node(value);
    node.next = this.head;
    this.head = node;
  }
  
  // O(n) - Add to tail
  append(value) {
    const node = new Node(value);
    if (!this.head) {
      this.head = node;
      return;
    }
    let curr = this.head;
    while (curr.next) curr = curr.next;
    curr.next = node;
  }
  
  // O(1) - Remove from head
  removeHead() {
    if (this.head) this.head = this.head.next;
  }
}

شرح الكود 📖

class Node: الـ node الواحدة - فيها value و next
class LinkedList: القائمة نفسها - فيها head بس!
prepend(): إضافة في الأول - O(1)
append(): إضافة في الآخر - O(n) لأن لازم نعدي على كل الـ nodes
removeHead(): حذف من الأول - O(1)