الخوارزميات
الخوارزمية سلسلة خطوات محددة تحل مسألة. نقارن الخوارزميات بكيفية نمو زمنها وذاكرتها مع حجم المدخلات n.
ترميز O الكبير
| التعقيد | الاسم | مثال |
|---|---|---|
| O(1) | ثابت | الوصول لعنصر بالفهرس |
| O(log n) | لوغاريتمي | البحث الثنائي |
| O(n) | خطي | المرور على قائمة |
| O(n log n) | — | الترتيب بالدمج |
| O(n²) | تربيعي | حلقتان متداخلتان |
| O(2ⁿ) | أسّي | تجربة كل المجموعات الجزئية |
البحث الثنائي
يعمل على مصفوفة مرتبة، ويقسم نطاق البحث إلى النصف في كل خطوة:
def binary_search(items, target):
lo, hi = 0, len(items) - 1
while lo <= hi:
mid = (lo + hi) // 2
if items[mid] == target:
return mid
if items[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1
الترتيب
الترتيب بالمقارنة لا يمكن أن يكون أسرع من O(n log n) في أسوأ حالة. الترتيب بالدمج يضمن ذلك، والترتيب السريع متوسطه O(n log n) وأسوأ حالاته O(n²). عملياً استخدم دالة اللغة المدمجة: sorted() في Python (خوارزمية Timsort المستقرة) أو array.sort() في JavaScript.
العودية
دالة تستدعي نفسها على مسألة أصغر، مع حالة أساس توقفها:
def factorial(n):
return 1 if n <= 1 else n * factorial(n - 1)
البرمجة الديناميكية
عندما تتكرر المسائل الفرعية نفسها، احفظ نتائجها بدل إعادة حسابها:
from functools import cache
@cache
def fib(n):
return n if n < 2 else fib(n - 1) + fib(n - 2)
بلا ذاكرة يكون التعقيد أسّياً، ومعها يصبح O(n).
اجتياز الرسوم البيانية
- BFS (عرضاً أولاً) بطابور: يجد أقصر مسار بعدد الحواف في رسم غير موزون.
- DFS (عمقاً أولاً) بمكدس أو بالعودية: لاكتشاف المكونات المتصلة والدورات.
- Dijkstra: أقصر مسار في رسم أوزانه غير سالبة.
نصائح
- حلّ المسألة بطريقة صحيحة وبسيطة أولاً، ثم قِس قبل أن تحسّن.
- تعقيد O(n²) مقبول لـ n صغيرة؛ المهم كيف يتصرف عند الأحجام الحقيقية لبياناتك.