אלגוריתמי מיון

בחרו אלגוריתם וצפו בו ממיין שלב אחר שלב

אלגוריתמי מיון הם מהנושאים הבסיסיים ביותר בקורסי מבני נתונים ואלגוריתמים. כל אחד מהאלגוריתמים כאן — בועות, בחירה, הכנסה, מיזוג, מהיר וערימה — פועל בצורה שונה ומתאים לנסיבות שונות. מיון מיזוג ומיון מהיר מגיעים ל-O(n log n) בממוצע ומשמשים בספריות סטנדרטיות. מיון בועות ומיון בחירה הם O(n²) אך פשוטים להבנה. לחצו על אלגוריתם ועל הפעל לראות כל שלב.

97
49
70
69
97
6
67
52
82
93
50
80
86
13
37
54
44
23
74
56
72
85
43
70
50
14
91
14
96
5
לא ממוין
משווה
מחליף
ציר / מפתח
ממוין

🔍 מה קורה עכשיו?

לחצו על הפעל או שלב כדי להתחיל את האלגוריתם.

שלב

1 / 0

פסאודו-קוד

1procedure bubbleSort(arr, n):
2 for i = 0 to n-1:
3 swapped = false
4 for j = 0 to n-i-2:
5 if arr[j] > arr[j+1]:
6 swap(arr[j], arr[j+1])
7 swapped = true
8 if not swapped:
9 break // המערך כבר ממוין
10 // האלמנט הגדול ביותר שלא מוין כעת במקומו
11 return arr

מיון בועות

איך זה עובד

עובר שוב ושוב על הרשימה, משווה אלמנטים סמוכים ומחליף אותם אם הם בסדר הלא נכון. המעבר חוזר על עצמו עד שהרשימה ממוינת.

💡 הרעיון המרכזי

אלמנטים גדולים "מבעבעים" למעלה למיקום הנכון שלהם בסוף המערך עם כל מעבר.

סיבוכיות

best

O(n)

average

O(n²)

worst

O(n²)

מקום

O(1)

יציב: true

מתי להשתמש

טוב למטרות לימודיות ומערכי נתונים קטנים. פשוט למימוש אך לא יעיל למערכים גדולים.

🎓 קוויז לימודי - מיון בועות

ציון: 0 / 5
שאלה 1 מתוך 5

מהי סיבוכיות הזמן הממוצעת של מיון בועות?

מדריך לאלגוריתמי מיון

מה הם אלגוריתמי מיון ולמה הם חשובים?

אלגוריתם מיון הוא נוהל שמקבל אוסף של ערכים ומחזיר אותם מסודרים לפי יחס סדר כלשהו — בדרך כלל מהקטן לגדול. זו אחת הבעיות הנחקרות ביותר במדעי המחשב, ולא במקרה: מיון הוא שלב הכנה שמאפשר לאלגוריתמים אחרים לעבוד מהר יותר. חיפוש בינארי דורש מערך ממוין, זיהוי כפילויות הופך לסריקה לינארית אחת אחרי מיון, ומיזוג של שתי רשימות ממוינות הוא O(n) במקום O(n·m).

מעבר לשימוש המעשי, אלגוריתמי מיון הם הדרך הנפוצה ביותר ללמד ניתוח סיבוכיות. הם קצרים מספיק כדי להבין אותם במלואם, אבל מציגים הבדלי ביצועים דרמטיים: על מערך של מיליון איברים, מיון בועות מבצע בערך 10¹² השוואות בעוד מיון מיזוג מבצע כ-2·10⁷. זהו פער של פי חמישים אלף, והוא מה שהופך את ההבדל בין O(n²) ל-O(n log n) למוחשי.

בוויזואליזציה שלמעלה כל עמודה מייצגת ערך, והצבעים מסמנים מה האלגוריתם עושה ברגע נתון: השוואה בין שני איברים, החלפה ביניהם, בחירת ציר, או סימון איבר שהגיע למקומו הסופי. הפעלת האלגוריתם שלב-אחר-שלב לצד הפסאודו-קוד מראה בדיוק איזו שורה אחראית לכל תנועה על המסך.

מיון בועות, בחירה והכנסה — האלגוריתמים הריבועיים

שלושת אלה חולקים סיבוכיות של O(n²) במקרה הממוצע, אך הם רחוקים מלהיות זהים. מיון בועות (Bubble Sort) עובר על המערך שוב ושוב ומחליף כל זוג סמוך שאינו בסדר הנכון, כך שהערך הגדול ביותר מבעבע לסוף בכל מעבר. עם דגל שמזהה מעבר ללא החלפות הוא מגיע ל-O(n) על מערך שכבר ממוין — יתרון שאין למיון בחירה.

מיון בחירה (Selection Sort) מוצא בכל איטרציה את המינימום מבין האיברים שנותרו ומציב אותו בסוף החלק הממוין. הוא תמיד מבצע בדיוק n(n-1)/2 השוואות — גם על קלט ממוין — אבל לכל היותר n-1 החלפות. זה הופך אותו לבחירה סבירה כשכתיבה לזיכרון יקרה משמעותית מקריאה, למשל בזיכרון פלאש.

מיון הכנסה (Insertion Sort) בונה מערך ממוין משמאל לימין ומכניס כל איבר חדש למקומו הנכון בתוכו. הוא האפקטיבי מבין השלושה בפועל: על קלט כמעט-ממוין הוא מתקרב ל-O(n), הוא יציב, והוא עובד במקום. מסיבה זו ספריות סטנדרטיות רבות עוברות למיון הכנסה עבור תת-מערכים קטנים בתוך מיון מהיר או מיון מיזוג.

מיון מיזוג, מיון מהיר ומיון ערימה — האלגוריתמים היעילים

מיון מיזוג (Merge Sort) מיישם הפרד ומשול: הוא מחלק את המערך לשניים, ממיין כל חצי רקורסיבית, וממזג את שתי התוצאות הממוינות למערך אחד. עומק הרקורסיה הוא log n והמיזוג בכל רמה עולה O(n), ומכאן O(n log n) — במקרה הטוב, הממוצע והגרוע כאחד. המחיר הוא O(n) זיכרון נוסף עבור מערך העזר.

מיון מהיר (Quick Sort) בוחר ציר (pivot), מחלק את המערך לאיברים קטנים ממנו וגדולים ממנו, וממיין כל צד רקורסיבית. בממוצע הוא O(n log n) עם קבועים קטנים מאוד ולוקליות זיכרון מצוינת, ולכן הוא בדרך כלל המהיר ביותר בפועל. אך אם הציר נבחר גרוע בעקביות — למשל האיבר הראשון על מערך שכבר ממוין — החלוקה מתנוונת והסיבוכיות מתדרדרת ל-O(n²).

מיון ערימה (Heap Sort) בונה ערימת מקסימום מהמערך ואז שולף שוב ושוב את המקסימום לסוף. הוא מבטיח O(n log n) גם במקרה הגרוע ומשתמש ב-O(1) זיכרון נוסף — שילוב שאין לאף אחד משני האחרים. בתמורה הוא סובל מלוקליות זיכרון גרועה, ולכן איטי ממיון מהיר בפועל למרות סיבוכיות זהה. אלגוריתם Introsort, המשמש בספריית C++, מתחיל כמיון מהיר ועובר למיון ערימה כשעומק הרקורסיה חורג — וכך מקבל את שני היתרונות.

יציבות, זיכרון וסיבוכיות — איך בוחרים אלגוריתם מיון

אלגוריתם מיון נקרא יציב אם הוא משמר את הסדר היחסי בין איברים בעלי מפתח זהה. זה קריטי במיון רב-שלבי: אם ממיינים רשימת עובדים לפי שם ואז לפי מחלקה, מיון יציב ישאיר את העובדים בכל מחלקה מסודרים לפי שם. מיון בועות, הכנסה ומיזוג הם יציבים; מיון בחירה, מהיר וערימה אינם.

בפועל, שפות תכנות מודרניות כמעט אף פעם לא משתמשות באלגוריתם יחיד. Python ו-Java משתמשות ב-Timsort, הכלאה של מיון מיזוג ומיון הכנסה שמזהה רצפים ממוינים קיימים בקלט ומנצלת אותם. התוצאה היא O(n) על נתונים כמעט-ממוינים — תרחיש נפוץ מאוד בעולם האמיתי — ו-O(n log n) מובטח במקרה הגרוע.

הכלל המעשי: לרשימות קצרות מאוד (עד כ-20 איברים) מיון הכנסה מנצח בזכות תקורה נמוכה. כשנדרשת יציבות או ביצועים צפויים — מיון מיזוג. כשמעוניינים במהירות גולמית וזיכרון מוגבל — מיון מהיר עם בחירת ציר אקראית או חציון-של-שלושה. וכשחייבים ערובה למקרה הגרוע ללא זיכרון נוסף — מיון ערימה.

שאלות נפוצות

מהו אלגוריתם המיון המהיר ביותר?

אין תשובה אחת. מבחינת סיבוכיות אסימפטוטית, מיון מיזוג, מיון מהיר ומיון ערימה כולם O(n log n) בממוצע. בפועל מיון מהיר הוא בדרך כלל המהיר ביותר על נתונים אקראיים בזכות קבועים קטנים ולוקליות זיכרון טובה, אך הוא מתדרדר ל-O(n²) עם בחירת ציר גרועה. על נתונים כמעט-ממוינים דווקא מיון הכנסה או Timsort יהיו מהירים יותר מכולם.

מה ההבדל בין מיון בועות למיון בחירה?

מיון בועות משווה זוגות סמוכים ומחליף ביניהם, כך שערכים גדולים מבעבעים לסוף; הוא מבצע הרבה החלפות אך מזהה מערך ממוין ועוצר ב-O(n). מיון בחירה סורק את כל החלק הלא ממוין כדי למצוא את המינימום ומבצע החלפה אחת בלבד לכל איטרציה; הוא תמיד O(n²) גם על קלט ממוין, אך מבצע לכל היותר n-1 החלפות. מיון בועות יציב, מיון בחירה אינו.

מה זה אלגוריתם מיון יציב?

אלגוריתם מיון יציב הוא כזה שמשמר את הסדר היחסי המקורי בין איברים שערך המפתח שלהם זהה. אם שני עובדים באותה מחלקה מופיעים ברשימה בסדר מסוים, מיון יציב לפי מחלקה ישאיר אותם באותו סדר ביניהם. מיון בועות, מיון הכנסה ומיון מיזוג הם יציבים. מיון בחירה, מיון מהיר ומיון ערימה אינם יציבים במימוש הסטנדרטי שלהם.

למה מיון מהיר נחשב מהיר אם הוא O(n²) במקרה הגרוע?

המקרה הגרוע של מיון מהיר מתרחש רק כשהציר מחלק את המערך בצורה מאוד לא מאוזנת בעקביות. עם בחירת ציר אקראית או שיטת חציון-של-שלושה, ההסתברות לכך זניחה, והמקרה הממוצע O(n log n) הוא מה שקורה כמעט תמיד. בנוסף, מיון מהיר עובד במקום ובעל לוקליות זיכרון מצוינת, כך שהקבוע הכפול שלו קטן משמעותית מזה של מיון מיזוג.

מתי כדאי להשתמש במיון מיזוג ולא במיון מהיר?

כשנדרשת יציבות, כשחייבים ערובה של O(n log n) גם במקרה הגרוע, או כשממיינים רשימה מקושרת — מיון מיזוג ממזג רשימות מקושרות ללא זיכרון נוסף משמעותי בעוד מיון מהיר מאבד את יתרון הגישה האקראית שלו. מיון מיזוג גם מתאים למיון חיצוני של קבצים גדולים מדי לזיכרון, כיוון שהוא קורא וכותב ברצף.

מהי סיבוכיות המקום של אלגוריתמי המיון?

מיון בועות, בחירה, הכנסה וערימה עובדים במקום ודורשים O(1) זיכרון נוסף. מיון מהיר דורש O(log n) עבור מחסנית הרקורסיה. מיון מיזוג הוא היוצא דופן עם O(n) זיכרון נוסף למערך העזר, וזהו המחיר העיקרי שלו מול מיון מהיר.