Why Data Structures؟
الكمبيوترات سريعة، لكنها ليست "سحرية". الموارد (الوقت والذاكرة) محدودة.
اختيار هيكل البيانات الصحيح هو الفرق بين برنامج يعمل في ثوانٍ وآخر يعمل في سنوات.
The Efficiency Goal
- تقليل وقت التنفيذ (Time Complexity).
- تقليل استهلاك الذاكرة (Space Complexity).
- الموازنة بينهما (Time-Space Tradeoff).
Algorithm Definition
هي مجموعة خطوات محددة بوضوح لحل مشكلة ما.
مثال: البحث عن رقم $k$ في مصفوفة حجمها $N$.
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 (المتسلسلات)
هذا القانون يظهر كثيراً في الحلقات المتداخلة (Nested Loops).
Modulo Operator (%)
باقي القسمة. يستخدم في جداول التجزئة (Hash Tables).
Result is in $[0, M-1]$
Java Generics
كيف نكتب كود يعمل مع أي نوع من البيانات (Integers, Strings, Employees)؟
قبل Java 5 (الطريقة القديمة)
private Object val;
public Object read() { return val; }
}
- نستخدم `Object` لكل شيء.
- نحتاج Casting عند الاسترجاع.
- الأخطاء تظهر وقت التشغيل (Runtime Error).
Java 5+ (Generics) ✨
private T val;
public T read() { return val; }
}
- نستخدم متغير للنوع `<T>`.
- لا نحتاج Casting.
- الأخطاء تظهر وقت الترجمة (Compile-time Safety).
جافا تقوم تلقائياً بالتحويل بين الأنواع الأولية (int, double) والكائنات المقابلة لها (Integer, Double) عند استخدامها في الـ Generics.
ArrayList<int> ❌ خطأ! يجب أن تكون ArrayList<Integer> ✅.
Creating Generic Arrays
في جافا، لا يمكنك إنشاء مصفوفة من النوع Generic مباشرة:
T[] arr = new T[10]; 🚫
الحل: أنشئ مصفوفة Object ثم قم بعمل Casting:
T[] arr = (T[]) new Object[10]; ✅
Logarithmic Growth
أي خوارزمية تقوم بقسمة المشكلة إلى نصفين في كل خطوة (مثل Binary Search)، فإن تعقيدها يكون:
$O(\log N)$
تذكر: $\log_2(1000) \approx 10$، $\log_2(1,000,000) \approx 20$. النمو بطيء جداً وممتاز!