📘 بطاقة الدرس
| المادة | الإعلام الآلي (Informatique) |
|---|---|
| المستوى | الثانية ثانوي (2AS) |
| الشعبة | تقني رياضي |
| الوحدة | الخوارزميات والبرمجة بلغة Pascal |
| الأسبوع | الخامس عشر – السادس عشر |
| مدة الدرس | ساعتان |
🎯 أهداف التعلم
- أن يميز المتعلم بين البحث التسلسلي والبحث الثنائي.
- أن يطبق خوارزمية البحث التسلسلي على مصفوفة أحادية البعد بلغة Pascal.
- أن يطبق خوارزمية البحث الثنائي على مصفوفة مرتبة بلغة Pascal.
- أن يحلل كفاءة كل خوارزمية من حيث عدد المقارنات.
- أن يحل تمارين بكالوريا باستخدام خوارزميات البحث.
🔍 تمهيد
عند التعامل مع كميات كبيرة من البيانات، تصبح عملية البحث عن عنصر معين داخل مصفوفة (Tableau) من أهم المهارات البرمجية التي يجب أن يتقنها المبرمج. تخيل أن لديك دفتر عناوين يحوي 1000 اسم وتريد البحث عن اسم معين — كيف ستفعل ذلك؟ هل ستتصفح الأسماء واحداً تلو الآخر من البداية؟ أم أن هناك طريقة أسرع؟ في هذا الدرس، سنتعلم خوارزميتين أساسيتين للبحث في المصفوفات: البحث التسلسلي (Recherche séquentielle) و البحث الثنائي (Recherche dichotomique)، وسنطبقهما بلغة Pascal مع أمثلة وتمارين بكالوريا محلولة.
تجدر الإشارة إلى أن درسنا هذا يندرج ضمن وحدة الخوارزميات والبرمجة، وهو امتداد طبيعي لدرس المصفوفات (Tableaux) في لغة Pascal ودرس الدوال والإجراءات في لغة Pascal، حيث سنستخدم المصفوفات والدوال معاً في بناء خوارزميات البحث.
1️⃣ البحث التسلسلي (Recherche séquentielle / Linear Search)
1.1 المفهوم
البحث التسلسلي هو أبسط خوارزميات البحث. تعتمد فكرته على المسح الخطي لعناصر المصفوفة واحداً تلو الآخر من البداية إلى النهاية، ومقارنة كل عنصر بالقيمة المبحوث عنها. بمجرد العثور على العنصر المطلوب، تتوقف الخوارزمية وتعيد موقع العنصر (Index). أما إذا وصلت إلى نهاية المصفوفة دون العثور عليه، فذلك يعني أن العنصر غير موجود.
💡 فكرة الخوارزمية
للبحث عن قيمة X في مصفوفة T ذات الحجم N:
- نضع
i ← 1(المؤشر على أول عنصر) - طالما
i ≤ NوT[i] ≠ Xنفذ:i ← i + 1 - إذا كان
i ≤ Nفإن العنصر موجود في الموقعi، وإلا فهو غير موجود.
1.2 المخطط الانسيابي
يمكن تمثيل خوارزمية البحث التسلسلي بمخطط انسيابي كالتالي:
- بداية ← إدخال N, T, X
- i ← 1
- حلقة تكرار: هل i ≤ N و T[i] ≠ X؟ نعم → i ← i + 1 ← كرر
- لا (خرجنا من الحلقة): هل i ≤ N؟
- نعم ← “العنصر موجود في الموقع i”
- لا ← “العنصر غير موجود”
- نهاية
1.3 البرمجة بلغة Pascal
لنكتب برنامجاً كاملاً يطبق البحث التسلسلي على مصفوفة من الأعداد الصحيحة:
Program RechercheSequencielle;
Uses WinCrt;
Var
T : Array[1..100] of Integer;
N, i, X : Integer;
Trouve : Boolean;
Begin
Write('أدخل عدد عناصر المصفوفة: ');
ReadLn(N);
{ إدخال عناصر المصفوفة }
For i := 1 to N Do
Begin
Write('T[', i, '] = ');
ReadLn(T[i]);
End;
Write('أدخل القيمة المبحوث عنها X: ');
ReadLn(X);
{ البحث التسلسلي }
i := 1;
Trouve := False;
While (i <= N) and (Trouve = False) Do
Begin
If T[i] = X Then
Trouve := True
Else
i := i + 1;
End;
{ عرض النتيجة }
If Trouve = True Then
WriteLn('✅ العنصر ', X, ' موجود في الموقع ', i)
Else
WriteLn('❌ العنصر ', X, ' غير موجود في المصفوفة');
End.
1.4 تحليل الكفاءة
| الحالة | عدد المقارنات | الوصف |
|---|---|---|
| أفضل حالة | 1 | العنصر موجود في أول موقع (T[1]) |
| أسوأ حالة | N | العنصر في آخر موقع أو غير موجود |
| متوسط الحالة | (N+1)/2 | احتمال متساوٍ لوجود العنصر في أي موقع |
نلاحظ أن كفاءة البحث التسلسلي هي O(N) (خطية)، أي أن زمن البحث يتناسب طردياً مع حجم المصفوفة.
2️⃣ البحث الثنائي (Recherche dichotomique / Binary Search)
2.1 المفهوم
البحث الثنائي هو خوارزمية أكثر ذكاءً ولكنها تتطلب أن تكون المصفوفة مرتبة ترتيباً متزايداً. تعتمد الفكرة على تقسيم المصفوفة إلى نصفين في كل خطوة، ومقارنة العنصر المطلوب مع العنصر الأوسط. إذا تطابقا، انتهى البحث. وإلا، نقرر ما إذا كان العنصر المطلوب يقع في النصف الأيمن أم الأيسر، ونكرر العملية على ذلك النصف فقط.
💡 تشبيه واقعي
تخيل أنك تبحث عن كلمة "بحث" في قاموس. هل تبدأ من الصفحة الأولى وتقلب صفحة صفحة؟ بالطبع لا! أنت تفتح القاموس في منتصفه تقريباً، وتنظر إلى أي صفحة وصلت. إذا كانت الكلمات في هذه الصفحة تأتي بعد "بحث" أبجدياً، تنتقل إلى النصف الأيسر، وإلى النصف الأيمن إن كانت قبلها. تكرر العملية حتى تجد الكلمة. هذا هو البحث الثنائي!
2.2 فكرة الخوارزمية
للبحث عن قيمة X في مصفوفة T مرتبة ترتيباً متزايداً ذات الحجم N:
- نضع
Gauche ← 1(الحد الأيسر) وDroit ← N(الحد الأيمن) - طالما
Gauche ≤ Droit:- نحسب
Milieu ← (Gauche + Droit) Div 2 - إذا كان
T[Milieu] = X→ العنصر موجود، توقف - إذا كان
T[Milieu] < X→Gauche ← Milieu + 1(ابحث في النصف الأيمن) - إذا كان
T[Milieu] > X→Droit ← Milieu - 1(ابحث في النصف الأيسر)
- نحسب
- إذا انتهت الحلقة دون العثور → العنصر غير موجود.
2.3 البرمجة بلغة Pascal
Program RechercheDichotomique;
Uses WinCrt;
Var
T : Array[1..100] of Integer;
N, i, X, Gauche, Droit, Milieu : Integer;
Trouve : Boolean;
Begin
Write('أدخل عدد عناصر المصفوفة: ');
ReadLn(N);
{ إدخال عناصر المصفوفة (مرتبة تصاعدياً) }
For i := 1 to N Do
Begin
Write('T[', i, '] = ');
ReadLn(T[i]);
End;
Write('أدخل القيمة المبحوث عنها X: ');
ReadLn(X);
{ البحث الثنائي }
Gauche := 1;
Droit := N;
Trouve := False;
While (Gauche <= Droit) and (Trouve = False) Do
Begin
Milieu := (Gauche + Droit) Div 2;
If T[Milieu] = X Then
Trouve := True
Else If T[Milieu] < X Then
Gauche := Milieu + 1 { ابحث في النصف الأيمن }
Else
Droit := Milieu - 1; { ابحث في النصف الأيسر }
End;
{ عرض النتيجة }
If Trouve = True Then
WriteLn('✅ العنصر ', X, ' موجود في الموقع ', Milieu)
Else
WriteLn('❌ العنصر ', X, ' غير موجود في المصفوفة');
End.
2.4 مثال توضيحي خطوة بخطوة
📝 مثال: البحث عن X = 23 في المصفوفة [3, 7, 12, 19, 23, 31, 42]
| الخطوة | Gauche | Droit | Milieu | T[Milieu] | مقارنة | إجراء |
|---|---|---|---|---|---|---|
| 1 | 1 | 7 | 4 | 19 | 19 < 23 | Gauche ← 5 |
| 2 | 5 | 7 | 6 | 31 | 31 > 23 | Droit ← 5 |
| 3 | 5 | 5 | 5 | 23 | 23 = 23 ✅ | العنصر موجود! |
لاحظ أننا احتجنا فقط 3 مقارنات للعثور على العنصر في مصفوفة من 7 عناصر، بينما كان البحث التسلسلي يحتاج إلى 5 مقارنات في أسوأ الأحوال.
2.5 تحليل الكفاءة
| الحالة | عدد المقارنات | الوصف |
|---|---|---|
| أفضل حالة | 1 | العنصر موجود في منتصف المصفوفة بالضبط |
| أسوأ حالة | log₂(N) + 1 | يحتاج إلى تقسيم المصفوفة حتى آخر عنصر |
| المتوسط | حوالي log₂(N) | كفاءة لوغاريتمية |
كفاءة البحث الثنائي هي O(log N) (لوغاريتمية)، وهي أفضل بكثير من O(N). لمصفوفة تحتوي على 1000 عنصر، يحتاج البحث التسلسلي إلى 1000 مقارنة في أسوأ الحالات، بينما يحتاج البحث الثنائي إلى 10 مقارنات فقط!
3️⃣ مقارنة بين الخوارزميتين
| المعيار | البحث التسلسلي | البحث الثنائي |
|---|---|---|
| شرط الترتيب | لا يشترط ترتيب المصفوفة | يجب أن تكون المصفوفة مرتبة |
| الكفاءة | O(N) — خطية | O(log N) — لوغاريتمية |
| سهولة التنفيذ | بسيط جداً | متوسط |
| متى نستخدمه | مصفوفات صغيرة أو غير مرتبة | مصفوفات كبيرة مرتبة |
| عدد المقارنات لـ N=1000 | حتى 1000 | حتى 10 |
✏️ تمارين بكالوريا محلولة
📝 تمرين 1: البحث عن عدد أولي في مصفوفة
أكتب برنامجاً بلغة Pascal يقرأ مصفوفة T من N عدد صحيح (N ≤ 100)، ثم يبحث عن أول عدد أولي في المصفوفة باستخدام البحث التسلسلي، ويعرض موقعه. إذا لم يوجد أي عدد أولي، يعرض رسالة "لا يوجد عدد أولي في المصفوفة".
ملاحظة: العدد الأولي هو عدد طبيعي أكبر من 1 يقبل القسمة فقط على 1 وعلى نفسه.
🟢 انقر هنا لرؤية الحل
Program ChercherPremier;
Uses WinCrt;
Var
T : Array[1..100] of Integer;
N, i, j : Integer;
EstPremier : Boolean;
Trouve : Boolean;
Begin
Write('أدخل عدد عناصر المصفوفة: ');
ReadLn(N);
For i := 1 to N Do
Begin
Write('T[', i, '] = ');
ReadLn(T[i]);
End;
{ البحث عن أول عدد أولي }
i := 1;
Trouve := False;
While (i <= N) and (Trouve = False) Do
Begin
If T[i] > 1 Then
Begin
EstPremier := True;
j := 2;
While (j <= Sqrt(T[i])) and (EstPremier = True) Do
Begin
If T[i] Mod j = 0 Then
EstPremier := False
Else
j := j + 1;
End;
If EstPremier Then
Trouve := True
Else
i := i + 1;
End
Else
i := i + 1;
End;
If Trouve = True Then
WriteLn('✅ أول عدد أولي هو ', T[i], ' في الموقع ', i)
Else
WriteLn('❌ لا يوجد عدد أولي في المصفوفة');
End.
📝 تمرين 2: بكالوريا — البحث الثنائي في مصفوفة مرتبة
مصفوفة T مكونة من N عدد صحيح (N ≤ 200) مرتبة ترتيباً تصاعدياً. أكتب برنامجاً بلغة Pascal يسمح بإدخال المصفوفة وقيمة X، ثم يبحث عن X باستخدام خوارزمية البحث الثنائي (Dichotomique). إذا وجد X، يعرض البرنامج الموقع الذي يوجد فيه. إذا لم يجده، يقوم بإدراج X في المكان المناسب للحفاظ على ترتيب المصفوفة، مع تحديث N (أي N ← N + 1).
🟢 انقر هنا لرؤية الحل
Program RechercheEtInsertion;
Uses WinCrt;
Var
T : Array[1..200] of Integer;
N, i, X, G, D, M, Pos : Integer;
Trouve : Boolean;
Begin
Write('أدخل عدد عناصر المصفوفة: ');
ReadLn(N);
For i := 1 to N Do
Begin
Write('T[', i, '] = ');
ReadLn(T[i]);
End;
Write('أدخل القيمة المبحوث عنها X: ');
ReadLn(X);
{ البحث الثنائي }
G := 1;
D := N;
Trouve := False;
While (G <= D) and (Trouve = False) Do
Begin
M := (G + D) Div 2;
If T[M] = X Then
Trouve := True
Else If T[M] < X Then
G := M + 1
Else
D := M - 1;
End;
If Trouve = True Then
WriteLn('✅ العنصر موجود في الموقع ', M)
Else
Begin
{ إدراج X في المكان المناسب }
Pos := G; { الموقع المناسب للإدراج }
{ إزاحة العناصر إلى اليمين }
For i := N DownTo Pos Do
T[i + 1] := T[i];
T[Pos] := X;
N := N + 1;
WriteLn('➕ تم إدراج ', X, ' في الموقع ', Pos);
WriteLn('المصفوفة بعد الإدراج:');
For i := 1 to N Do
Write(T[i], ' ');
End;
End.
📝 تمرين 3: مقارنة عدد المقارنات
مصفوفة T تحتوي على 500 عدد صحيح مرتب ترتيباً تصاعدياً. إذا طبقنا خوارزميتي البحث التسلسلي والبحث الثنائي للبحث عن عنصر موجود في الموقع 423:
- كم مقارنة سيجريها البحث التسلسلي؟
- كم مقارنة سيجريها البحث الثنائي تقريباً؟
- في أي حالة يكون البحث التسلسلي أفضل من البحث الثنائي؟
🟢 انقر هنا لرؤية الحل
أ) البحث التسلسلي: سيحتاج إلى 423 مقارنة (لأنه يبدأ من أول عنصر ويتوقف عند الموقع 423).
ب) البحث الثنائي: في أسوأ حالة، يحتاج إلى log₂(500) + 1 ≈ 9 + 1 = 10 مقارنات. ولكن العثور على العنصر قد يكون في وقت أبكر، لذا تقريباً بين 7 و 10 مقارنات.
ج) متى يكون البحث التسلسلي أفضل؟
- عندما يكون العنصر المبحوث عنه في بداية المصفوفة (المواقع 1، 2، 3).
- عندما تكون المصفوفة غير مرتبة (البحث الثنائي لا يعمل).
- عندما تكون المصفوفة صغيرة جداً (أقل من 10 عناصر) — الفرق ضئيل.
- عندما يكون تنفيذ الكود أبسط وأقل عرضة للأخطاء (للبرامج الصغيرة).
📌 ملخص الدرس
- البحث التسلسلي: يمسح المصفوفة عنصراً عنصراً من البداية. لا يشترط الترتيب. كفاءته O(N).
- البحث الثنائي: يقسم المصفوفة مرتبة إلى نصفين في كل خطوة. يشترط الترتيب التصاعدي. كفاءته O(log N).
- طريقة التنفيذ في Pascal: نستخدم حلقة
Whileمع شرط الاستمرار في البحث، ومتغير منطقيTrouveللإشارة إلى العثور على العنصر. - في البحث الثنائي:
Milieu ← (Gauche + Droit) Div 2هو مفتاح الخوارزمية. - خوارزميات البحث هي أساس بنى البيانات المتقدمة مثل قواعد البيانات والفهارس (Indexes).
- اختيار الخوارزمية المناسبة يعتمد على حجم البيانات وترتيبها — فكر دائماً قبل أن تبرمج!
📍 دروس مشابهة:
- المصفوفات (Tableaux) في لغة Pascal — أحادية وثنائية البعد — الثانية ثانوي (شعبة تقني رياضي) — الإعلام الآلي
- الدوال والإجراءات في لغة Pascal (Functions et Procedures) — الثانية ثانوي (شعبة تقني رياضي) — الإعلام الآلي
مدونة التربية و التعليم في الجزائر – دروس، فروض، نتائج امتحانات مدونة التربية والتعليم في الجزائر | تحضير الدروس، فروض واختبارات، نتائج البكالوريا وBEM، مسابقات التوظيف، والتوجيه المدرسي للطلاب وأولياء الأمور.