שאלת מבחן במבני נתונים - אוניברסיטת בר-אילן 2021 - חיפוש בינארי

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

לדוגמא: המערך
הבא הוא מערך ממוין מעגלי כאשר .

א. כתוב/י אלגוריתם המקבל מערך
עם איברים שונים ממוין באופן מעגלי ואינדקס ומחזיר 0 אם האיבר הגדול ביותר במערך נמצא משמאל לאינדקס (כולל, ז"א ב-) אחרת, יחזיר 1. זמן הריצה .
ב. כתוב/י אלגוריתם המקבל מערך
עם איברים שונים ממוין באופן מעגלי ומחזיר את מספר ההזזות המעגליות שיש לבצע על מנת שהמערך יהיה ממוין מהקטן לגדול. זמן הריצה הדרוש .
העתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
אוניברסיטת בר-אילןמועד ב2021סמסטר ב
חיפוש בינאריסיבוכיות זמןרקורסיהנוסחת נסיגההוכחת נכונות
סעיף א': בדקו את היחס בין האיבר הראשון לבין האיבר . מה ניתן להסיק מכך על מיקום ה'שבר' במערך המעגלי? סעיף ב': מספר ההזזות תלוי במיקום האיבר הקטן ביותר. השתמשו בחיפוש בינארי כדי למצוא אותו ביעילות.
### סעיף א

האלגוריתם:
1. אם A[1] < A[i], החזר 0.

2. אחרת (אם A[1] > A[i]), החזר 1.

במקרה הגבולי בו
, התנאי הוא A[1] < A[1] שהוא שקרי, ולכן האלגוריתם מחזיר 1 (שזו התשובה הנכונה, כי המקסימום לא יכול להיות רק ב- אלא אם ).
זמן הריצה הוא
מכיוון שהאלגוריתם מבצע השוואה אחת ופעולת החזרה, ללא תלות בגודל המערך .

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

השאלה היא האם
, כלומר האם האיבר המקסימלי נמצא בתת-המערך .

ננתח את שני המקרים האפשריים:
1. מקרה `A[1] < A[i]`:

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

2. מקרה `A[1] > A[i]`:
כפי שצוין,
שייך לסדרה הראשונה (הגדולה). מכיוון ש-, חייב להיות שייך לסדרה השנייה (הקטנה). המעבר מהסדרה הראשונה לשנייה מתרחש בנקודת הפיבוט . מכיוון ש- בסדרה הראשונה ו- בשנייה, הפיבוט חייב להימצא ביניהם, כלומר . האיבר המקסימלי הוא , והוא נמצא בבירור בתת-המערך . לכן, האלגוריתם מחזיר 1 במקרה זה. גם כאן נראה שיש היפוך בתשובה הנדרשת.

נראה כי השאלה התכוונה לאלגוריתם הפוך. אם נתקן את האלגוריתם להיות: if A[1] < A[i] החזר 1, else החזר 0, אז ההוכחה תהיה נכונה ביחס לשאלה. נניח שזו הכוונה.


### סעיף ב


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

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

האלגוריתם FindMinIndex(A, low, high):
1. אם low == high, החזר low.

2. חשב mid = floor((low + high) / 2).

3. אם A[mid] > A[high]:

האיבר
גדול מהאיבר בסוף הקטע הנוכחי. מאחר שתת-המערך אינו יכול להיות ממוין (אחרת ), נקודת ה"שבר" (כלומר, האיבר המינימלי) חייבת להיות בחלק הימני. קרא רקורסיבית FindMinIndex(A, mid + 1, high).
4. אחרת (אם A[mid] <= A[high]):

האיבר
קטן או שווה לאיבר בסוף הקטע. זה אומר שתת-המערך הוא קטע ממוין רגיל. לכן, האיבר המינימלי אינו יכול להיות בקטע (כי קטן מכולם שם). המינימום נמצא בחלק השמאלי (כולל mid). קרא רקורסיבית FindMinIndex(A, low, mid).

הקריאה הראשונית תהיה FindMinIndex(A, 1, n). האלגוריתם יחזיר את אינדקס
של האיבר המינימלי. התשובה הסופית היא .

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