Bubble Sort (מיון בועות)
עודכן לאחרונה
מיון בועות עובר שוב ושוב על הרשימה, משווה כל זוג איברים סמוכים ומחליף ביניהם אם הם בסדר הלא נכון. אחרי כל מעבר מלא, הערך הגדול ביותר שנותר "מבעבע" למקומו הנכון בסוף, ולכן כל מעבר בודק איבר אחד פחות. לחצו על הפעלה למעלה כדי לראות את ההשוואות וההחלפות, או עברו עליהן אחת אחת.
זה אחד מאלגוריתמי המיון הפשוטים ביותר להבנה, ולכן הוא אלגוריתם ראשון מצוין, אבל זמן הריצה שלו, O(n²), הופך אותו ללא מעשי עבור קלטים גדולים.
סיבוכיות זמן וזיכרון
| מקרה | סיבוכיות | הערות |
|---|---|---|
| המקרה הטוב | O(n) | כבר ממוין, עם בדיקת יציאה מוקדמת |
| המקרה הממוצע | O(n²) | סדר אקראי |
| המקרה הגרוע | O(n²) | ממוין בסדר הפוך |
| זיכרון | O(1) | במקום, רק משתנה זמני אחד |
| יציב | כן | איברים שווים שומרים על הסדר היחסי שלהם |
צעד אחר צעד
| צעד | מה קורה |
|---|---|
| 1 | מתחילים בתחילת המערך. |
| 2 | משווים את האיבר הנוכחי לאיבר הבא. |
| 3 | אם הם לא בסדר, מחליפים ביניהם. |
| 4 | זזים מקום אחד ימינה וחוזרים על כך עד הסוף (מעבר אחד). |
| 5 | חוזרים על המעברים; כל מעבר מקבע עוד איבר אחד בסוף. |
| 6 | עוצרים כשמעבר מלא לא מבצע אף החלפה. |
דוגמה מפורטת
מיון של [5, 2, 4, 1]:
| מעבר | מערך | פעולה |
|---|---|---|
| 1 | [2, 4, 1, 5] | מחליפים 5,2, אחר כך 5,4, ואז 5,1; 5 מבעבע לסוף. |
| 2 | [2, 1, 4, 5] | 2,4 בסדר; מחליפים 4,1; 4,5 בסדר; 4 נמצא עכשיו במקומו. |
| 3 | [1, 2, 4, 5] | מחליפים 2,1; השאר כבר בסדר; 2 במקומו. |
| 4 | [1, 2, 4, 5] | מעבר מלא לא מבצע אף החלפה, ולכן המערך ממוין והאלגוריתם עוצר. |
מתי להשתמש במיון בועות
| השתמשו בו כאשר | הימנעו ממנו כאשר |
|---|---|
| מלמדים או לומדים איך עובדים מיונים מבוססי השוואה | ממיינים קלטים גדולים, שבהם O(n²) איטי מדי |
הקלט זעיר או כמעט ממוין (עם יציאה מוקדמת הוא מתקרב ל-O(n)) | אתם צריכים את המיון הכללי המהיר ביותר: השתמשו ב-quicksort או במיון מיזוג |
| אתם צריכים מיון יציב במקום עם כמעט אפס קוד | הנתונים בסדר אקראי והביצועים חשובים |
| רוצים לבדוק במעבר אחד אם רשימה קצרה כבר ממוינת | כתיבות רבות יקרות (למשל זיכרון פלאש); מיון בחירה מבצע פחות החלפות |
קוד Bubble Sort
מימוש נקי של Bubble Sort שאפשר להריץ, ב-Python, JavaScript, Java, C++, C, Pseudocode. בחרו שפה, העתיקו את הקוד, או פתחו אותו טעון מראש בעורך האונליין של Coddy.
קוד Bubble Sort ב-Python
1def bubble_sort(a):2 n = len(a)3 for i in range(n - 1):4 swapped = False5 for j in range(n - 1 - i):6 if a[j] > a[j + 1]:7 a[j], a[j + 1] = a[j + 1], a[j]8 swapped = True9 if not swapped:10 break # no swaps means the list is already sorted11 return a12
13
14nums = [5, 1, 4, 2, 8]15print("Before:", nums)16bubble_sort(nums)17print("After: ", nums)קוד Bubble Sort ב-JavaScript
1function bubbleSort(a) {2 for (let end = a.length - 1; end > 0; end--) {3 let swapped = false;4 for (let j = 0; j < end; j++) {5 if (a[j] > a[j + 1]) {6 [a[j], a[j + 1]] = [a[j + 1], a[j]];7 swapped = true;8 }9 }10 if (!swapped) break; // Already sorted: stop early11 }12 return a;13}14
15const data = [5, 2, 9, 1, 7, 3];16console.log("Before:", data);17console.log("Sorted:", bubbleSort([...data]));קוד Bubble Sort ב-Java
1import java.util.Arrays;2
3public class Main {4 static void bubbleSort(int[] arr) {5 for (int i = arr.length - 1; i > 0; i--) {6 boolean swapped = false;7 for (int j = 0; j < i; j++) {8 if (arr[j] > arr[j + 1]) {9 int tmp = arr[j];10 arr[j] = arr[j + 1];11 arr[j + 1] = tmp;12 swapped = true;13 }14 }15 if (!swapped) break; // already sorted16 }17 }18
19 public static void main(String[] args) {20 int[] arr = {5, 1, 4, 2, 8, 3};21 System.out.println("Before: " + Arrays.toString(arr));22 bubbleSort(arr);23 System.out.println("After: " + Arrays.toString(arr));24 }25}קוד Bubble Sort ב-C++
1#include <iostream>2#include <utility>3#include <vector>4
5void printVec(const std::vector<int>& a) {6 for (int x : a) std::cout << x << " ";7 std::cout << "\n";8}9
10void bubbleSort(std::vector<int>& a) {11 for (size_t pass = 0; pass + 1 < a.size(); ++pass) {12 bool swapped = false;13 // Each pass bubbles the largest remaining value to the end14 for (size_t j = 0; j + 1 < a.size() - pass; ++j) {15 if (a[j] > a[j + 1]) {16 std::swap(a[j], a[j + 1]);17 swapped = true;18 }19 }20 if (!swapped) break; // already sorted21 }22}23
24int main() {25 std::vector<int> data = {5, 1, 4, 2, 8, 3};26 std::cout << "Before: ";27 printVec(data);28 bubbleSort(data);29 std::cout << "After: ";30 printVec(data);31 return 0;32}קוד Bubble Sort ב-C
1#include <stdbool.h>2#include <stdio.h>3
4void printArr(const int a[], int n) {5 for (int i = 0; i < n; i++) printf("%d ", a[i]);6 printf("\n");7}8
9void bubbleSort(int a[], int n) {10 for (int pass = 0; pass < n - 1; pass++) {11 bool swapped = false;12 // Each pass bubbles the largest remaining value to the end13 for (int j = 0; j < n - 1 - pass; j++) {14 if (a[j] > a[j + 1]) {15 int tmp = a[j];16 a[j] = a[j + 1];17 a[j + 1] = tmp;18 swapped = true;19 }20 }21 if (!swapped) break; // already sorted22 }23}24
25int main(void) {26 int data[] = {5, 1, 4, 2, 8, 3};27 int n = sizeof(data) / sizeof(data[0]);28 printf("Before: ");29 printArr(data, n);30 bubbleSort(data, n);31 printf("After: ");32 printArr(data, n);33 return 0;34}קוד Bubble Sort ב-Pseudocode
1DECLARE nums : ARRAY[1:7] OF INTEGER2DECLARE n : INTEGER3n ← 74nums[1] ← 75nums[2] ← 36nums[3] ← 97nums[4] ← 18nums[5] ← 59nums[6] ← 810nums[7] ← 211DECLARE i : INTEGER12DECLARE j : INTEGER13DECLARE temp : INTEGER14
15// Bubble the largest remaining value to the end on each pass16FOR i ← 1 TO n - 117 FOR j ← 1 TO n - i18 IF nums[j] > nums[j + 1] THEN19 temp ← nums[j]20 nums[j] ← nums[j + 1]21 nums[j + 1] ← temp22 ENDIF23 NEXT j24NEXT i25
26FOR i ← 1 TO n27 OUTPUT nums[i]28NEXT iשאלות נפוצות על מיון בועות
מהי סיבוכיות הזמן של מיון בועות?
O(n²) במקרה הממוצע ובמקרה הגרוע בגלל הלולאות המקוננות. עם אופטימיזציה של יציאה מוקדמת הוא יכול להגיע ל-O(n) על מערך שכבר ממוין. הוא משתמש ב-O(1) זיכרון נוסף.האם מיון בועות יציב?
למה קוראים לו מיון בועות?
מה ההבדל בין מיון בועות למיון הכנסה?
O(n²), יציבים ועובדים במקום, אבל הם מזיזים נתונים בצורה שונה: מיון בועות מחליף שוב ושוב זוגות סמוכים שאינם בסדר, ואילו מיון הכנסה לוקח כל איבר ומחליק אותו אחורה למקומו הנכון בחלק הממוין. מיון הכנסה בדרך כלל מבצע פחות כתיבות ורץ מהר יותר בפועל, במיוחד על נתונים כמעט ממוינים.מתי כדאי להשתמש במיון בועות במקום ב-quicksort?
O(n log n) של quicksort מוחץ את O(n²) של מיון בועות בכל קלט שאינו זעיר. מיון בועות שווה בחירה רק כשהרשימה קטנה מאוד או כמעט ממוינת, או כשרוצים את המיון היציב הפשוט ביותר האפשרי לצורכי לימוד.האם אופטימיזציית היציאה המוקדמת משנה את המקרה הגרוע של מיון בועות?
O(n) על קלט ממוין, אבל מערך ממוין בסדר הפוך עדיין דורש את כל ההשוואות, ולכן המקרה הגרוע נשאר O(n²). האופטימיזציה עוזרת רק במקרה הטוב ובמקרים הכמעט ממוינים.