Bubblه خوارزمية الفرز في Java: برنامج فرز المصفوفات ومثال
⚡ ملخص ذكي
Bubblه خوارزمية الفرز في Java يقارن هذا البرنامج عناصر المصفوفة المتجاورة بشكل متكرر ويبدلها حتى يصبح التسلسل مرتبًا. تشرح هذه المقالة آلية العمل، والرمز الزائف، والشرح الكامل. Java التنفيذ، والنسخة المُحسّنة، وتحليل التعقيد، والمقارنات العملية مع تقنيات الفرز الأخرى.

ما هي تفاصيل Bubblه فرز؟
Bubblخوارزمية eSort هي خوارزمية فرز بسيطة تعتمد على المقارنة، حيث تقارن العنصر الأول في المصفوفة بالعنصر التالي. إذا كان العنصر الحالي أكبر عدديًا من العنصر التالي، يتم تبديل العنصرين. وبالمثل، تجتاز الخوارزمية جميع عناصر المصفوفة.
يستمد هذا الخوارزمية اسمها من الطريقة التي ترتفع بها أكبر قيمة في المنطقة غير المرتبة تدريجيًا إلى موقعها النهائي، تمامًا مثل فقاعة تصعد إلى سطح الماء. بعد المرور الأول الكامل، يشغل العنصر الأكبر الفهرس الأخير. بعد المرور الثاني، يتم تثبيت ثاني أكبر عنصر في مكانه، وتتكرر العملية حتى يصبح المصفوفة مرتبة بالكامل.
في هذه المقالة، سنقوم بإنشاء Java برنامج للتنفيذ Bubblفرز e. تحقق من مخرجات الكود التي ستساعدك على فهم منطق البرنامج، ثم راجع النسخة المُحسّنة وتحليل التعقيد الذي يليها.
كيف يمكن لل Bubblهل تعمل خوارزمية الفرز الإلكتروني؟
Bubblتعتمد خوارزمية الفرز الإلكتروني على المرور المتكرر على المصفوفة. في كل مرور، تبدأ العملية من الفهرس الأول وتنتهي عند نهاية المنطقة غير المرتبة حاليًا، حيث تتم مقارنة القيم المتجاورة وتبديلها.ping يتم فرزها كلما ظهرت بترتيب خاطئ. ولأن أكبر قيمة متبقية تنتقل دائمًا إلى أقصى يمين المنطقة غير المصنفة، فإن المنطقة تتقلص بمقدار موضع واحد بالضبط بعد كل عملية فرز.
يمكن تقسيم العملية الكاملة إلى أربع خطوات قابلة للتكرار:
- قارن: افحص العنصر الموجود في الفهرس j-1 مقابل العنصر الموجود في الفهرس j.
- مبادلة: إذا كان العنصر الأيسر أكبر من العنصر الأيمن، فقم بتبديل القيمتين باستخدام متغير مؤقت.
- تقدم: انتقل موضعًا واحدًا إلى اليمين وكرر العملية حتى الوصول إلى نهاية المنطقة غير المصنفة.
- كرر: ابدأ تمريرة جديدة على منطقة أقصر بعنصر واحد، وتوقف بعد n-1 تمريرة أو عندما لا تقوم أي تمريرة بعمليات تبديل.
الجدول أدناه tracهذه هي مصفوفة العينة {860، 8، 200، 9} المستخدمة في البرنامج لاحقًا في هذه الصفحة. وهي توضح بدقة القيمة التي تستقر في موضعها النهائي في نهاية كل دورة.
| تجاوز | المصفوفة في بداية المرور | المقارنات التي تم إجراؤها | المصفوفة في نهاية المرور | العنصر مغلق |
|---|---|---|---|---|
| 1 | 860 ، 8 ، 200 ، 9 | 3 | 8 ، 200 ، 9 ، 860 | 860 |
| 2 | 8 ، 200 ، 9 ، 860 | 2 | 8 ، 9 ، 200 ، 860 | 200 |
| 3 | 8 ، 9 ، 200 ، 860 | 1 | 8 ، 9 ، 200 ، 860 | 9 |
| 4 | 8 ، 9 ، 200 ، 860 | 0 | 8 ، 9 ، 200 ، 860 | 8 |
لاحظ أن المرور الثالث يُجري مقارنة دون تبديل. يكتشف التنفيذ المُحسَّن هذه الحالة ويتوقف فورًا، وهو التحسين الأهم الذي يُمكن تطبيقه على هذه الخوارزمية.
Bubblالشفرة الزائفة لخوارزمية فرز e
قبل الكتابة Java تساعد هذه الصيغة في التعبير عن المنطق بلغة شبه رمزية محايدة. يتضمن الإصدار أدناه علامة الخروج المبكر، لذا فهو يغطي السلوك الكلاسيكي والمُحسَّن.
procedure bubbleSort(array A, integer n) for i from 0 to n - 2 do swapped := false for j from 1 to n - i - 1 do // compare the adjacent pair if A[j - 1] > A[j] then swap A[j - 1] and A[j] swapped := true end if end for // no swap in a full pass means the array is sorted if swapped = false then break end if end for end procedure
تتحكم الحلقة الخارجية في عدد مرات المرور، بينما تتحكم الحلقة الداخلية في المقارنات داخل كل مرة مرور. الحد الأعلى للحلقة الداخلية هو n – i – 1 لأن آخر i خانة تحمل قيمها النهائية.
Java برنامج للتنفيذ Bubblه فرز
يقوم البرنامج التالي بترتيب مصفوفة أعداد صحيحة ترتيبًا تصاعديًا. تم الاحتفاظ بعبارات طباعة إضافية داخل الحلقات عمدًا، لأن قراءة تمرير البيانات بشكل جانبي قد تكون غير ضرورية. tracيُعدّ هذا أسرع طريقة للمبتدئين لفهم كيفية تراكم عمليات التبادل.
package com.guru99; public class BubbleSort { public static void main(String[] args) { int arr[] = {860, 8, 200, 9}; System.out.println("---Array BEFORE Bubble Sort---"); printArray(arr); bubbleSort(arr); //sorting array elements using bubble sort System.out.println("---Array AFTER Bubble Sort---"); printArray(arr); } static void bubbleSort(int[] array) { int n = array.length; int temp = 0; for(int i = 0; i < n; i++) // Looping through the array length { System.out.println("Sort Pass Number " + (i + 1)); for(int j = 1; j < (n - i); j++) { System.out.println("Comparing " + array[j - 1] + " and " + array[j]); if(array[j - 1] > array[j]) { //swap elements temp = array[j - 1]; array[j - 1] = array[j]; array[j] = temp; System.out.println(array[j] + " is greater than " + array[j - 1]); System.out.println("Swapping Elements: New Array After Swap"); printArray(array); } } } } static void printArray(int[] array){ for(int i = 0; i < array.length; i++) { System.out.print(array[i] + " "); } System.out.println(); } }
الإخراج:
---Array BEFORE Bubble Sort--- 860 8 200 9 Sort Pass Number 1 Comparing 860 and 8 860 is greater than 8 Swapping Elements: New Array After Swap 8 860 200 9 Comparing 860 and 200 860 is greater than 200 Swapping Elements: New Array After Swap 8 200 860 9 Comparing 860 and 9 860 is greater than 9 Swapping Elements: New Array After Swap 8 200 9 860 Sort Pass Number 2 Comparing 8 and 200 Comparing 200 and 9 200 is greater than 9 Swapping Elements: New Array After Swap 8 9 200 860 Sort Pass Number 3 Comparing 8 and 9 Sort Pass Number 4 ---Array AFTER Bubble Sort--- 8 9 200 860
Code تفسير: استخدم فرز الفقاعات يستقبل الأسلوب المصفوفة كمرجع، لذا يرى المستدعي النتيجة المرتبة دون أي قيمة مُعادة. المتغير درجة الحرارة يحتفظ بقيمة واحدة أثناء عملية التبديل بين الأسطر الثلاثة، ولهذا السبب لا تحتاج الخوارزمية إلا إلى ذاكرة إضافية مقدارها O(1). ن – ي يضمن شرط الحلقة الداخلية عدم إعادة زيارة المواضع المصنفة مسبقًا في النهاية.
الأمثل Bubblه فرز البرنامج في Java
يُجري البرنامج أعلاه دائمًا n-1 دورة، حتى عندما يتم فرز المصفوفة مبكرًا. إضافة علامة منطقية واحدة تُصلح هذا القصور. إذا انتهت دورة كاملة دون أي تبديل، يُضمن فرز المصفوفة ويمكن إيقاف الحلقة الخارجية فورًا.
package com.guru99; public class OptimizedBubbleSort { public static void main(String[] args) { int arr[] = {5, 12, 33, 47, 58}; bubbleSort(arr); System.out.println(java.util.Arrays.toString(arr)); } static void bubbleSort(int[] array) { int n = array.length; int passes = 0; for (int i = 0; i < n - 1; i++) { boolean swapped = false; for (int j = 1; j < n - i; j++) { if (array[j - 1] > array[j]) { int temp = array[j - 1]; array[j - 1] = array[j]; array[j] = temp; swapped = true; } } passes++; // Early exit: the array is already sorted if (!swapped) { break; } } System.out.println("Passes executed: " + passes); } }
الإخراج:
Passes executed: 1 [5, 12, 33, 47, 58]
كانت مصفوفة الإدخال مرتبة بالفعل، لذا انتهت النسخة المُحسّنة بعد تمريرة واحدة بدلاً من أربع. في البيانات شبه المرتبة، يُحوّل هذا التغيير عبء العمل التربيعي إلى عبء عمل خطي تقريبًا، وهو السبب الرئيسي. Bubblلا يزال فرز e يظهر في التعليمات البرمجية الحقيقية من وقت لآخر.
التعقيد الزمني والتعقيد المكاني لـ Bubblه فرز
يصف التعقيد كيفية ازدياد وقت التشغيل مع ازدياد حجم المدخلات. Bubble يتم تحديد عدد المقارنات في النسخة غير المحسنة عند n(n-1)/2، مما يضعها بقوة في الفئة التربيعية.
| سيناريو | شرط الإدخال | تعقيد الوقت | تعقيد الفضاء |
|---|---|---|---|
| افضل حالة | تم فرز المصفوفة مسبقًا، نسخة محسّنة | O (ن) | يا (1) |
| حالة متوسطة | العناصر بترتيب عشوائي | س (ن²) | يا (1) |
| الحالة الأسوأ | مصفوفة مرتبة بترتيب عكسي | س (ن²) | يا (1) |
لأن كل عملية تبادل تتم داخل المصفوفة الأصلية ويتم استخدام متغير مؤقت واحد فقط، Bubblخوارزمية e Sort هي خوارزمية فرز موضعي بمساحة تخزين إضافية ثابتة O(1). وهي أيضًا خوارزمية فرز مستقرة، مما يعني أن سجلين يحملان نفس المفتاح يحتفظان بترتيبهما النسبي الأصلي بعد الفرز.
مزايا وعيوب Bubblه فرز
يساعدك فهم كلا الجانبين على تحديد متى تكون الخوارزمية خيارًا مقبولًا ومتى يجب استبدالها.
المزايا
- بساطة: يمكن تلخيص المنطق في حوالي عشرة أسطر، مما يسهل كتابته بشكل صحيح في ظروف المقابلة.
- عملية التشغيل في الموقع: لا يتم تخصيص أي مصفوفة مساعدة، لذا فإن استخدام الذاكرة لا يزداد مع حجم الإدخال.
- المزيد: تحتفظ المفاتيح المتساوية بترتيبها الأصلي، وهو أمر مهم عند فرز السجلات حسب حقل ثانوي.
- الكشف المبكر عن الخروج: يشير العلم المبدل إلى مصفوفة مرتبة بالفعل في تمريرة واحدة.
عيوب
- النمو التربيعي: يتطلب فرز 10,000 عنصر ما يقرب من 50 مليون مقارنة في أسوأ الحالات.
- يكتب بإفراط: تُجري الخوارزمية عمليات تبديل أكثر بكثير من فرز التحديد، الذي يستهلك الكثير من الذاكرة مع عمليات كتابة بطيئة.
- ضعف قابلية التوسع: تُفضل أحمال العمل الإنتاجية دائمًا تقريبًا استخدام Quicksort أو Merge Sort أو طريقة Arrays.sort المدمجة.
💡 نصيحة: في الانتاج Java يفضل البرمجة Arrays.sort () بالنسبة للعناصر الأولية و Collections.sort() بالنسبة للقوائم. يستخدم كلاهما خوارزميات مُحسَّنة للغاية، وهما Dual-Pivot Quicksort وTimSort على التوالي، والتي تتفوق على الخوارزميات المكتوبة يدويًا. Bubblرتب حسب رتبة الحجم.
Bubblالفرز الإلكتروني مقابل أنواع الفرز الأخرى Algorithms
الجدول أدناه يقارن Bubblقم بالفرز باستخدام تقنيات الفرز التي سيتعرف عليها المبتدئون لاحقًا، حتى تتمكن من رؤية أين يفوز كل منها بالضبط.
| خوارزمية | أفضل حالة | متوسط الحالة | الحالة الأسوأ | الفضاء | مستقر |
|---|---|---|---|---|---|
| Bubblه فرز | O (ن) | س (ن²) | س (ن²) | يا (1) | نعم |
| اختيار نوع | س (ن²) | س (ن²) | س (ن²) | يا (1) | لا |
| ترتيب بالإدراج | O (ن) | س (ن²) | س (ن²) | يا (1) | نعم |
| الترتيب السريع | س (ن سجل ن) | س (ن سجل ن) | س (ن²) | O (تسجيل ن) | لا |
| نوع كومة | س (ن سجل ن) | س (ن سجل ن) | س (ن سجل ن) | يا (1) | لا |
Bubblيشترك كل من فرز e وفرز الإدراج في نفس الحالة الخطية المثلى، لكن فرز الإدراج يُجري عددًا أقل من عمليات التبديل على البيانات المرتبة جزئيًا. بينما يُجري فرز التحديد دائمًا n-1 عملية تبديل بالضبط، مما يجعله فيtracيُعدّ فرز البيانات السريع (Quicksort) أو فرز الكومة (Heap Sort) خيارًا مناسبًا عندما تكون عمليات الكتابة مكلفة، على الرغم من أنه يُضحّي بالاستقرار. بالنسبة لأي مصفوفة يزيد حجمها عن بضع مئات من العناصر، يُعدّ فرز البيانات السريع (Quicksort) أو فرز الكومة (Heap Sort) الخيار الأمثل.
بمجرد أن تعتاد على أنماط اجتياز المصفوفات المستخدمة هنا، ستظهر بنية الحلقة نفسها في العديد من التمارين الكلاسيكية مثل متسلسلة فيبوناتشي Java و مبادئ السلوك Java برنامج الكلمات المتناظرة. Revتأمل Java المصفوفات وعلى نطاق أوسع Java البرنامج التعليمي سيؤدي ذلك إلى تعزيز الأسس التي تعتمد عليها هذه الخوارزمية.
