طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 101 · تركيب البيانات والخوارزميات
الدرس 4 · الوحدة 2: تحليل وتقييم الخوارزميات

الحالة الأفضل والأسوأ والمتوسطة

الخوارزمية نفسها قد تنهي في خطوة أو في مليون خطوة؛ يعتمد ذلك على المدخل. ⏱ نحو 25 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تميّز الحالة الأفضل والأسوأ والمتوسطة لخوارزمية.
  • تحسب عدد عمليات الخوارزمية بعدّاد في الكود.
  • تشرح لماذا نعتمد على الحالة الأسوأ غالبًا.
  • تحلل البحث الخطي والترتيب بالإدراج في الحالات الثلاث.

١الخوارزمية نفسها، وأعمال مختلفة

البحث الخطي: نفحص العناصر من الأول حتى نجد المطلوب. كم مقارنة يحتاج؟ يعتمد على مكان العنصر. جرّب المحاكاة مرتين: مرة لعنصر في البداية، ومرة لعنصر غير موجود:

🎬 بحث خطي عن 14 (أول عنصر)

مقارنةتبديل أو نقلالمحور أو الوسطفي مكانه النهائي أو وُجد
🎬 بحث خطي عن 40 (غير موجود)

مقارنةتبديل أو نقلالمحور أو الوسطفي مكانه النهائي أو وُجد

٢ثلاث حالات نحللها

الحالةمتى تحدث في البحث الخطي؟عدد المقارنات (n عنصرًا)
الأفضل Best Caseالعنصر في الموقع الأول.1
الأسوأ Worst Caseالعنصر في الآخر، أو غير موجود.n
المتوسطة Average Caseالعنصر في موقع عشوائي.نحو n ÷ 2

نتحقق من ذلك بالحساب. نبحث عن كل عنصر في قائمة من 10 عناصر، ونعدّ المقارنات:

main.py
def linear_search(a, x):    comparisons = 0    for v in a:        comparisons += 1        if v == x:            break    return comparisons a = list(range(1, 11))          # 10 عناصرcounts = [linear_search(a, x) for x in a]print("كل الحالات:", counts)print("الأفضل:", min(counts))print("الأسوأ:", max(counts))print("المتوسط:", sum(counts) / len(counts))
Shell×
>>> %Run main.py
كل الحالات: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
الأفضل: 1
الأسوأ: 10
المتوسط: 5.5
>>>

٣لماذا نهتم بالحالة الأسوأ أكثر؟

لأنها ضمان: مهما كان المدخل، لن تتجاوز الخوارزمية هذا العدد. نظام حجز الطيران لا يكفيه أن يكون سريعًا «في المتوسط»؛ يجب ألا يتعطل أبدًا في أسوأ يوم.

الحالةفائدتها
الأفضلقليلة الفائدة؛ تحدث نادرًا ولا تضمن شيئًا.
المتوسطةتصف الأداء المعتاد، لكن حسابها يحتاج معرفة توزيع المدخلات.
الأسوأالأهم عادة: حد أعلى مضمون للأداء.

٤الحالات في خوارزمية ترتيب

الترتيب بالإدراج يُدخل كل عنصر في مكانه الصحيح في الجزء المرتب. شاهد كيف يختلف عمله على قائمة شبه مرتبة وعلى قائمة معكوسة:

🎬 الإدراج على قائمة شبه مرتبة

مقارنةتبديل أو نقلالمحور أو الوسطفي مكانه النهائي أو وُجد
🎬 الإدراج على قائمة معكوسة

مقارنةتبديل أو نقلالمحور أو الوسطفي مكانه النهائي أو وُجد
main.py
def insertion_comparisons(a):    a = list(a)    count = 0    for i in range(1, len(a)):        j = i        while j > 0:            count += 1            if a[j - 1] > a[j]:                a[j - 1], a[j] = a[j], a[j - 1]                j -= 1            else:                break    return count n = 100print("مرتبة:", insertion_comparisons(range(n)))print("معكوسة:", insertion_comparisons(range(n, 0, -1)))
Shell×
>>> %Run main.py
مرتبة: 99
معكوسة: 4950
>>>

على قائمة مرتبة أصلًا: 99 مقارنة فقط (الحالة الأفضل). وعلى قائمة معكوسة: 4950 مقارنة (الحالة الأسوأ). الخوارزمية نفسها، والفرق 50 ضعفًا بسبب المدخل وحده.

توقّع وتحقّق

أسوأ حالة للبحث الخطي في 50 عنصرًا:

العنصر في الآخر أو غير موجود.

أفضل حالة للبحث الخطي:

مقارنة واحدة.

الحالة التي تعطي ضمانًا للأداء:

حد أعلى.

الترتيب بالإدراج أسرع ما يكون على قائمة:

لا إزاحات.

الخلاصة

تحدٍّ برمجي: حلّل البحث الخطي

متوسط

قائمة فيها 8 أسماء. احسب عدد مقارنات البحث الخطي عن كل اسم، وعن اسم غير موجود، ثم اطبع الأفضل والأسوأ والمتوسط (للأسماء الموجودة).

المطلوب:
  • دالة تُرجع عدد المقارنات (تتوقف عند الإيجاد).
  • اطبع: غير موجود: 8
  • اطبع: الأفضل: 1 ثم الأسوأ: 8 ثم المتوسط: 4.5

ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:

main.py
names = ["أحمد", "سارة", "خالد", "منى", "فهد", "ريم", "علي", "هند"]
المطلوب×
غير موجود: 8
الأفضل: 1
الأسوأ: 8
المتوسط: 4.5
💡 تلميح 1
counts = [comparisons(names, x) for x in names]
💡 تلميح 2
المتوسط: sum(counts) / len(counts)

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

main.py
names = ["أحمد", "سارة", "خالد", "منى", "فهد", "ريم", "علي", "هند"] def comparisons(a, x):    c = 0    for v in a:        c += 1        if v == x:            break    return c print("غير موجود:", comparisons(names, "سلمان"))counts = [comparisons(names, x) for x in names]print("الأفضل:", min(counts))print("الأسوأ:", max(counts))print("المتوسط:", sum(counts) / len(counts))
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس