אלגוריתמי סינון
הוצג| English | משמעות |
|---|---|
| bubble sort/ˈbʌbl sɔːt/ | מיון בועה |
| insertion sort/ɪnˈsɜːʃn sɔːt/ | מיון הכנסה |
| in place/ɪn pleɪs/ | במקום |
| stable/ˈsteɪbl/ | יציב |
הסידור שהאיטיות בו מכוונת
- לכל ספרייה רצינית יש אלגוריתם סידור שאין בתיק נסיעה מבקשים ממך לכתוב. סידור בועות וסידור הכנסה הם שניהם $O(n^2)$, ושניהם מובסים על ידי כל סידור סביר ברשימה גדולה.
- הם מופיעים בתיק anyway, ולטובת סיבה טובה: הם קצרים מספיק כדי לעקוב אחריהם ידנית, ועקוב אחרי אחד מהם הוא הדרך ללמוד מה סידור בעצם עושה למערך.
- יש גם טענה אמיתית לסידור הכנסה. ברשימה קטנה או כזו שכבר מסודרת כמעט לחלוטין, זו באמת התוכנית המהירה ביותר שקיימת, וספריות אמיתיות מעבירות אליה בדיוק עבור המקרים האלה.
- שיעור זה עוסק בסידור בועות ובסידור הכנסה: האלגוריתמים, התנהגותם, ואיפה כל אחד מהם מנצח.
בועות (Bubble sort)
FOR pass ← 1 TO n - 1
swapped ← FALSE
FOR i ← 1 TO n - pass
IF A[i] > A[i + 1] THEN
swap A[i], A[i + 1]
swapped ← TRUE
ENDIF
NEXT i
IF NOT swapped THEN // already sorted
EXIT FOR
ENDIF
NEXT pass
- בכל מעבר משווים זוגות סמוכים ומחליפים כל זוג שיצא מהסדר, כך שהערך הגדול שנותר "מבועבל" לקצה.
- לאחר מעבר $k$ ה$k$ אלמנטים האחרונים הם סופיים, ולכן הלולאה הפנימית עצומה ב$n - \text{pass}$.
- הדגל
swappedמאפשר עצירה מוקדמת: אם במעבר שלם לא נעשתה החלפה, הרשימה מסודרת.
סידור הכנסה
FOR i ← 2 TO n
key ← A[i]
j ← i - 1
WHILE j >= 1 AND A[j] > key DO
A[j + 1] ← A[j] // shift right
j ← j - 1
ENDWHILE
A[j + 1] ← key // drop it in
NEXT i
- הוא בונה חלק מסודר בהתחלה, הגדל באלמנט אחד בכל פעם. כל אלמנט חדש מוחזץ בצד כ
key, אלמנטים גדולים יותר מוזזים ימינה לפתיחת מרווח, והמפתח מוטבע בתוך המרווח. - זוהי הדרך שבה רוב האנשים מסדרים משחקת קלפים, והאנלוגיה שהמבחן מצפה לה.

החלק השמאלי מסודר, החלק הימני אינו נוגע בו, הגבול זז ימינה
אלגוריתמי סינון
השוו אלמנטים שכנים, החליפו אם נדרש
צעדו דרך סינון בועות: בכל מעבר הערך הגדול צף לסוף הרשימה.
סינון בועות פועל באמצעות:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
כל מעבר מבצע החלפות של זוגות שכנים, ומ"בועבל" את האלמנט הגדול לסוף.
המורכבות הזמנית הממוצעת/הגרועה ביותר של סינון בועות היא:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
שתי לולאות מקוננות מעל n אלמנטים נותנות O(n²); המקרה הטוב (כבר מסודר) הוא O(n) עם יציאה מוקדמת.
דוגמה פתורה: עקוב מעבר אחד
- עקוב את המעבר הראשון בסידור בועות על 5, 3, 8, 1.
- השווה בין 5 ל-3: לא בסדר, החלף, מקבלים 3, 5, 8, 1. השווה בין 5 ל-8: בסדר, אין החלפה. השווה בין 8 ל-1: החלף, מקבלים 3, 5, 1, 8.
- לאחר מעבר אחד הערך הגדול ביותר, 8, נמצא במיקומו הסופי, ומעכשיו ניתן לדלג על השוואה אחת בכל מעבר.
- עקוב כעת את השלב השלישי של סידור ההכנסה על 3, 5, 8, 1. המפתח הוא 1. הזז את 8, 5 ו-3 כל אחד במופע אחד ימינה, ולאחר מכן הנח את 1 בראש: 1, 3, 5, 8. הצג את המערך לאחר כל שלב; זהו המקום שבו המטרה היא לקבל נקודות.
סינון הכנסה בונה את התוצאה המסודרת על ידי:
Difficulty 1/5 · 100 coins + a small bonus on first completion today
הוא יוצר קדמה ממוינת בצד שמאל, מזיז אלמנטים גדולים יותר ימינה כדי להניח כל מפתח במקומו.
איך בירור ההכנסה מניח את כל אלמנט חדש?
Difficulty 1/5 · 100 coins + a small bonus on first completion today
השארת המפתח בצד והזזה הם מה שמבדיל בין בירור זה לבין החלפות סמוכות חוזרות של בירור הבועות.
ביצועים
| סידור בועות | סידור הכנסה | |
|---|---|---|
| מקרה מיטבי | $O(n)$, מעבר אחד ללא החלפות | $O(n)$, כבר מסודר, ללא הזזות |
| ממוצע וגרוע | $O(n^2)$ | $O(n^2)$ |
| זיכרון נוסף | $O(1)$, בתוך המערך | $O(1)$, בתוך המערך |
| יציבות | כן | כן, יציב |
- בתוך המערך (in place) אומר שהוא דורש רק כמות קבועה של זיכרון נוסף, ומסדר בתוך המערך עצמו. יציב אומר ששתי ערכים שווים שומרים על הסדר היחסי המקורי שלהם, מה שחשוב כאשר רשימה already מסודרת לפי שדה אחר.
- שניהם מגיעים ל$O(n)$ על נתונים שכבר מסודרים, אך רק אם לסידור בועות יש את הדגל
swapped. ללאו, הוא מבצע תמיד את כל המעברים.
לאחר מעבר ראשון של בירור בועות על 5, 3, 8, 1, מה יהיה המערך? כתוב את ארבעת המספרים ברווחים.
Difficulty 1/5 · 100 coins + a small bonus on first completion today
5 ו-3 מתחלפים, 5 ו-8 לא מתחלפים, 8 ו-1 מתחלפים. הערך הגדול ביותר הגיע לקצה, ולכן המעבר הבא יכול להיות קצר בהשוואה אחת.
דוגמה פתורה: איזה סידור, ולמה
- רשימה של 200,000 רשומות חייבת להיות מסודרת מאפס. שניהם לא: שניהם הם $O(n^2)$, לכן נדרש סידור מיזוג או מהיר ב$O(n \log n)$. אמור זאת במקום לבחור את הרע מביניהם.
- רשימה מסודרת של 10,000 מקבלת 5 רשומות חדשות בסוף וחייבת להיות מסודרת שוב. סידור הכנסה: הנתונים כמעט מסודרים, כך שכל מפתח חדש יוזז רק למרחק קצר והוא מתקרב ל$O(n)$.
- דוגמה לימודית חייבת להיות מעוקבת ידנית על נייר. סידור בועות: הוא הפשוט ביותר לעקוב אחריו, והוא השימוש העיקרי שנותר לו.
- נמקו על בסיס מצב הנתונים וגודלם, ולא לפי העדפה כללית.
התאם כל רעיון בירור למה שהוא אומר.
Difficulty 2/5 · 140 coins + a small bonus on first completion today
בועות מתחלפות עם שכנים, הכנסה מרחיבה קדמה מסודרת; שניהם O(n²) במקרה הגרוע; יציבות נוגעת בסדר של ערכים שווים.
סינון בהכנסה פועל בקרבת ל-O(n) על מערכים קטנים או כמעט-מסודרים, מכיוון שמעטים זקוקים להזזה.
Difficulty 1/5 · 100 coins + a small bonus on first completion today
על נתונים כמעט-מסודרים כל פריט חדש נמצא כבר כמעט במקומו — ולכן סינון בהכנסה עדיף על סיווגים מורכבים יותר על כניסות קטנות.
איזה מהנפואר נכון עבור both בועות וסינון בהכנסה? בחר את כולם החלופות הרלוונטיות.
Difficulty 2/5 · 140 coins + a small bonus on first completion today
על רשימה גדולה ולא-מסודרת, סיווג O(n log n) מנצח באופן משמעותי. אמירה זו היא התשובה הנכונה, ולא בחירת הפחות גרועה מבין השתיים.
מדוע מעבר אחד אינו מספיק
- שתי השיטות מבצעות מעברים חוזרים, והמבחן מבדיל ביניהן לפי מה שמעבר אחד משיג ומתי הן נעצרות.
- במעבר של מינון בועות (bubble sort) משווים זוגות שכנים ומחליפים אותם, כך שמעבר אחד מוביל את האלמנט הגדול הנותר למקומו הסופי. המינון כולו דורש $n - 1$ מעברים.
- במעבר של מינון הכנסה (insertion sort) לוקחים את האלמנט הבא ומזיזים אותו החוצה לתוך החלק שכבר ממוין, כך שע לאחר $k$ מעברים, ה-$k$ אלמנטים הראשונים ממונים בינם עצמם אך עדיין לא במיקום הסופי שלהם.
- מינון בועות ניתן לשפר באמצעות סימן: אם במעבר לא נעשה שום החלפה, הרשימה כבר ממוינת והאלגוריתם נעצר. בנתונים הקרובים למיון זה הופך אותו למעבר אחד.
- ללא הסימן, שתי השיטות הן $n^2$ במקרה הרע, ולכן הן בחירה גרועה לקובץ גדול, ולכן השאלות במבחן עוסקות בקבצים קטנים.
רשימה מסודרת של 10,000 רשומות מקבלת 5 רשומות חדשות בסוף. איזה סיווג מתאים למיזוג מחדש שלה?
Difficulty 1/5 · 100 coins + a small bonus on first completion today
נתונים כמעט-מסודרים הם בדיוק המקרה הטוב ביותר של סינון בהכנסה, המתקרב ל-O(n). ספריות בפועל עוברות אליו לשם כך.
התאם כל סיווג לכך שהעברה אחת מגיעה.
Difficulty 2/5 · 140 coins + a small bonus on first completion today
ההבדל הזה הוא מה ששאלת עקבות (trace question) בוחנת בעצם. דגל בועות מאפשר גם לו לעצור מוקדם על נתונים כמעט-מסודרים, דבר שסינון בהכנסה מטפל בו היטב בכל מקרה.
סימונים נופלים מהיד
- מינון בועות משווה זוגות שכנים. תשובה המשווה אלמנט לכל שאר האלמנטים מתארת אלגוריתם אחר.
- הלולאה הפנימית מתקצרת בכל מעבר, כי סוף המערך כבר סופי. הסבירו למה.
- מינון הכנסה מזיז אלמנטים ימינה כדי לפתוח מקום; הוא אינו מחליף שוב ושוב. ההבדל הזה הוא ליבת האלגוריתם.
- שתי השיטות הן $O(n^2)$ בערך הממוצע ובמקרה הרע, והן $O(n)$ במקרה הטוב. ציינו את המקרה עם הסדר.
הבנתך מושלמת
- מינון בועות: מעברים חוזרים המשווים זוגות שכנים ומחליפים אותם, הגדול מועף לסוף, הלולאה הפנימית מתקצרת בכל מעבר, עם סימן
swappedליציאה מוקדמת - מינון הכנסה: צומח חלק ממוין בראש, מחזיק כל אלמנט צירוף בצד, מזיז אלמנטים גדולים יותר ימינה ומכניס את האלמנט לצירוף למקום הפתוח
- שתי השיטות הן $O(n^2)$ בערך הממוצע ובמקרה הרע, $O(n)$ במקרה הטוב, במקום ויציבותיות
- מינון הכנסה מנצח באמת ברשימות קטנות או קרובות למיון; עבור רשימה גדולה ולא ממוינת, אף אחת מהן היא התשובה הנכונה