خوارزميات البحث
| English | العربية |
|---|---|
| linear search/ˈlɪnɪə sɜːtʃ/ | البحث الخطي |
| binary search/ˈbaɪnəri sɜːtʃ/ | البحث الثنائي |
عشرون سؤالًا لمليون اسم
- دفتر هواتف يحتوي على مليون اسم. عند فحصها واحدًا تلو الآخر، ستحتاج إلى نصف مليون مقارنة تقريبًا قبل العثور على الاسم المطلوب.
- افتحها من المنتصف بدلاً من ذلك، حدد أي نصف يحتوي الاسم، وتجاهل النصف الآخر. كرر العملية. تصل إلى أي اسم في عشرين مقارنة.
- نصف مليون مقابل عشرين ليس توفيرًا بسيطًا؛ بل هو الفرق بين برنامج يعمل وبرنامج لا يمكن استخدامه. ويكلف هذا شيئًا واحدًا: القائمة يجب أن تكون مرتبة مسبقًا.
- هذه الدرس是关于 البحث الخطي والبحث الثنائي، وكيفية أداء كل منهما، وكيفية الاختيار بينهما.
البحث الخطي
FOR i ← 1 TO n
IF A[i] = target THEN
RETURN i
ENDIF
NEXT i
RETURN -1 // not found
- يبدأ من البداية، يقارن كل عنصر مع العنصر المستهدف، ويتوقف عند العثور على تطابق أو الوصول إلى النهاية.
- يعمل على أي قائمة، مرتبة أو غير مرتبة، وأي بنية يمكن المرور خلالها.
- أسوأ حالة: العنصر المستهدف هو الأخير أو غير موجود، لذا يتم مقارنة جميع $n$ عناصر، وهو $O(n)$. في المتوسط، حوالي النصف.

واحدًا تلو الآخر، من البداية
البحث الخطي:
البحث الخطي لا يتطلب تحضيرًا ويعمل على أي قائمة، وفي أسوأ الأحوال يكون O(n).
يُعد البحث الخطي الخيار الأفضل عندما تكون البيانات:
مع عدم وجود ترتيب يمكن استغلاله (أو قائمة صغيرة)، يتجنب البحث الخطي تكلفة الترتيب مسبقًا.
البحث الثنائي
low ← 1 ; high ← n
WHILE low <= high DO
mid ← (low + high) DIV 2
IF A[mid] = target THEN
RETURN mid
ENDIF
IF A[mid] < target THEN
low ← mid + 1
ELSE high ← mid - 1
ENDWHILE
RETURN -1
- يتطلب أن تكون البيانات مرتبة. قارن العنصر الأوسط مع العنصر المستهدف: إذا تطابق، توقف؛ إذا كان المستهدف أكبر، تجاهل النصف السفلي؛ وإلا تجاهل النصف العلوي.
- كل مقارنة تنصف النطاق المتبقي للبحث، لذا فإن عدد المقارنات هو $O(\log_2 n)$.
- لهذا السبب يحتاج مليون عنصر إلى حوالي عشرين مقارنة: $2^{20}$ هو مجرد أكثر من مليون.
خوارزميات البحث
الثنائي يُضعف النطاق في كل خطوة
الخطي يفحص كل عنصر؛ والثنائي يُضعف قائمة مرتبة — مقارنة أقل بكثير.
تعقيد الوقت في أسوأ الأحوال للبحث الثنائي هو:
تقليص النطاق في كل خطوة يعطي عددًا من المقارنات لوغاريتمي.
كم عدد المقارنات التي يحتاجها البحث الثنائي لمليون عنصر مرتب؟
$\log_2(1\,000\,000) \approx 20$ — حوالي 20 مقارنة.
يمكن استخدام البحث الثنائي على أي قائمة، مرتبة أم غير مرتبة.
يحدد أي نصف يتم تجاهله بالمقارنة مع العنصر الأوسط، وهو ما يكون ذا معنى فقط إذا كانت البيانات مرتبة.
البحث الثنائي هو O(log n) لأن كل مقارنة ____ النطاق المتبقي للبحث.
عشرون عملية نصف تأخذ مليون إلى واحد، ولهذا فإن 2^20 الذي يزيد قليلاً عن المليون هو الرقم الذي يجب تذكره.
مثال محلول: تتبع بحث ثنائي
- القائمة المرتبة هي 2، 5، 8، 12، 16، 23، 38، 56، 72، 91. تابع البحث عن 23.
lowهو 1،highهو 10، لذاmidهو 5، يحمل القيمة 16. 16 أصغر من 23، لذا نتجاهل النصف السفلي:lowيصبح 6.low6،high10، لذاmidهو 8، يحمل القيمة 56. 56 أكبر من 23، لذاhighيصبح 7.low6،high7، لذاmidهو 6، يحمل القيمة 23. تم العثور عليه، في ثلاث مقارنات حيث كان البحث الخطي سيستغرق ستة.- اعرض
low،high،midوالقيمة في كل خطوة. معظم الدرجات تكمن في التتبع، وليس في الإجابة النهائية.
في القائمة المرتبة 2, 5, 8, 12, 16, 23, 38, 56, 72, 91، كم عدد المقارنات التي يحتاجها البحث الثنائي لإيجاد 23؟
mid 5 يحمل 16 (صغير جدًا)، mid 8 يحمل 56 (كبير جدًا)، mid 6 يحمل 23. كان البحث الخطي سيستغرق ست مقارنات.
الاختيار بينهما
| خطي | ثنائي | |
|---|---|---|
| البيانات يجب أن تكون مرتبة | لا | نعم |
| مقارنات، أسوأ حالة | $n$ | $\log_2 n$ |
| مليون عنصر | حتى 1,000,000 | حوالي 20 |
| بدلات | قوائم غير مرتبة أو صغيرة، قوائم مربوطة | مصفوفات مرتبة كبيرة، تُبحث بشكل متكرر |
- الترتيب الأول يكلف أكثر من بحث خطي واحد، لذا البحث الثنائي يكون مجديًا فقط عندما تكون القائمة مرتبة مسبقًا أو سيتم البحث فيها مرات عديدة.
- البحث الثنائي يحتاج أيضًا إلى وصول مباشر إلى العنصر الأوسط، مما تتوفر له المصفوفة ولا تتوفر للقائمة المرتبطة.
مثال محلول: تبرير الاختيار
- يبحث برنامج في قائمة غير مرتبة مكونة من 50 سجلًا مرة واحدة. البحث الخطي: ترتيب القائمة أولًا سيكلف أكثر بكثير من الـ 50 مقارنة التي يحتاجها البحث.
- يبحث برنامج في مصفوفة مرتبة مكونة من مليون سجل آلاف المرات في الثانية. البحث الثنائي: البيانات مرتبة مسبقًا وكل بحث يكلف حوالي 20 مقارنة بدلاً من مليون ممكن.
- يبحث برنامج في قائمة مرتبطة. البحث الخطي: البحث الثنائي يحتاج إلى القفز مباشرة إلى العنصر الأوسط، والقائمة المرتبطة يمكن متابعتها فقط من البداية.
- سمِّ الخوارزمية، ثم الخاصية الخاصة بـ البيانات التي تحدد اختيارها.
طابق كل بحث مع حقائقه الأساسية.
البحث الثنائي أسرع بكثير (O(log n)) لكنه يعمل فقط على بيانات مرتبة؛ بينما يعمل البحث الخطي في أي مكان بـ O(n).
متى يكون البحث الخطي هو الخيار الأفضل؟ حدد كل الخيارات الصحيحة.
الحالة الأخيرة هي بالضبط المكان الذي يفوز فيه البحث الثنائي. إن الترتيب مسبقًا يكلف أكثر من بحث خطي واحد، لذا فهو مجدي فقط عند إجراء العديد من عمليات البحث.
تكلفة الحفاظ على الملف مرتبًا
- البحث الثنائي متاح فقط على قائمة مرتبة، وهذا الترتيب ليس مجانيًا. السؤال الذي يطلب منك تبرير اختيارك هو يطلب منك تقدير تكلفته.
- إذا كانت البيانات تُبحث غالبًا وتُعدَّل نادرًا، رتّبها مرة واحدة وستكون كل searches لاحق $\log_2 n$. هذا هو الحال قاموس أو جدولlookup.
- إذا كانت البيانات تتغير باستمرار، يجب أن يحافظ كل إدخال على الترتيب، مما يكلف إزاحة العناصر اللاحقة. يمكن حينها أن يكون البحث الخطي على بيانات غير مرتبة هو الأقل تكلفة إجماليًا.
- الأرقام تجعل الحجة ملموسة: مليون سجل يحتاج حتى مليون مقارنة بشكل خطي، ولكن فقط 20 بالبحث الثنائي، لأن $2^{20} > 10^6$.
- لذلك تذكر الإجابة المصححة كلا الجانبين: مدى تكرار البحث، ومدى تكرار التغيير.
ضع تبرير اختيار خوارزمية البحث بالترتيب.
السؤال التبريري يطلب الموازنة، وليس الفائز. البحث الثنائي على قائمة تتغير باستمرار قد يكلف أكثر إجماليًا من البحث الخطي.
علامات ضائعة
- البحث الثنائي يتطلب بيانات مرتبة. قول "إنه أسرع" دون شرط الترتيب يفقد الدرجة.
- كل خطوة تُضعف النطاق إلى النصف، ومن هنا يأتي $\log_2 n$. قدم السبب، لا الرمز فقط.
- يجب أن يكون كلا الخوارزميتين قادرين على الإبلاغ عن عدم العثور، وهذا هو الغرض من
-1وشروط الحلقة. - البحث الثنائي يحتاج إلى وصول مباشر، لذا فهو لا ينطبق على قائمة مترابطة حتى لو كانت القائمة مرتبة.
لقد فهمت الأمر
- البحث الخطي يقارن كل عنصر من البداية، ويعمل على أي قائمة، وهو $O(n)$
- البحث الثنائي يحتاج بيانات مرتبة مع وصول مباشر، ويقارن العنصر الأوسط ويضعف النطاق في كل مرة، مما يعطي $O(\log_2 n)$: حوالي 20 مقارنة لمليون عنصر
- تتبع البحث الثنائي بإظهار
low،high،midوالقيمة في كل خطوة - اختر من البيانات: غير مرتبة، صغيرة أو قائمة مترابطة تعني خطي؛ كبيرة، مرتبة ومطلوبة بحثاً متكرراً تعني ثنائي