Introduction to Data Structures

الفصل الأول: الأساسيات الرياضية والبرمجية

الهدف: فهم الـ Generics في Java، ومراجعة الرياضيات اللازمة لتحليل الخوارزميات.
1

Why Data Structures؟

الكمبيوترات سريعة، لكنها ليست "سحرية". الموارد (الوقت والذاكرة) محدودة.
اختيار هيكل البيانات الصحيح هو الفرق بين برنامج يعمل في ثوانٍ وآخر يعمل في سنوات.

The Efficiency Goal

  • تقليل وقت التنفيذ (Time Complexity).
  • تقليل استهلاك الذاكرة (Space Complexity).
  • الموازنة بينهما (Time-Space Tradeoff).

Algorithm Definition

هي مجموعة خطوات محددة بوضوح لحل مشكلة ما.
مثال: البحث عن رقم $k$ في مصفوفة حجمها $N$.

2

Mathematics Review

Logarithms & Exponents

  • $X^A X^B = X^{A+B}$
  • $(X^A)^B = X^{AB}$
  • $\log_{X}(AB) = \log_X A + \log_X B$
  • $\log_A B = \frac{\log_C B}{\log_C A}$

مهم جداً لتحليل الـ Big-O لاحقاً.

Series (المتسلسلات)

$\sum_{i=0}^{N} i = \frac{N(N+1)}{2} \approx \frac{N^2}{2}$

هذا القانون يظهر كثيراً في الحلقات المتداخلة (Nested Loops).

Modulo Operator (%)

باقي القسمة. يستخدم في جداول التجزئة (Hash Tables).

$N \pmod M$
Result is in $[0, M-1]$
3

Java Generics

كيف نكتب كود يعمل مع أي نوع من البيانات (Integers, Strings, Employees)؟

قبل Java 5 (الطريقة القديمة)

class MemoryCell {
  private Object val;
  public Object read() { return val; }
}
  • نستخدم `Object` لكل شيء.
  • نحتاج Casting عند الاسترجاع.
  • الأخطاء تظهر وقت التشغيل (Runtime Error).

Java 5+ (Generics) ✨

class MemoryCell<T> {
  private T val;
  public T read() { return val; }
}
  • نستخدم متغير للنوع `<T>`.
  • لا نحتاج Casting.
  • الأخطاء تظهر وقت الترجمة (Compile-time Safety).
Auto-boxing & Unboxing:
جافا تقوم تلقائياً بالتحويل بين الأنواع الأولية (int, double) والكائنات المقابلة لها (Integer, Double) عند استخدامها في الـ Generics.
ArrayList<int> ❌ خطأ! يجب أن تكون ArrayList<Integer> ✅.
🛡️ EXAM VAULT (خزنة الاختبار)
TRAP / خطأ شائع

Creating Generic Arrays

في جافا، لا يمكنك إنشاء مصفوفة من النوع Generic مباشرة:
T[] arr = new T[10]; 🚫
الحل: أنشئ مصفوفة Object ثم قم بعمل Casting:
T[] arr = (T[]) new Object[10];

CALCULATION / النمو

Logarithmic Growth

أي خوارزمية تقوم بقسمة المشكلة إلى نصفين في كل خطوة (مثل Binary Search)، فإن تعقيدها يكون:
$O(\log N)$
تذكر: $\log_2(1000) \approx 10$، $\log_2(1,000,000) \approx 20$. النمو بطيء جداً وممتاز!

→ السابق (الفهرس) الفصل التالي (Ch 2) ←