320 likes | 581 Views
תרגול 4. ADTs: Array, Queue, Stack, Linked List. ADT – מבנה נתונים אבסטרקטי. דוגמאות:. ADT – מבנה נתונים אבסטרקטי. דוגמאות:. ADT – מבנה נתונים אבסטרקטי. דוגמאות:. הערה חשובה : מבני גישה אבסטרקטיים ניתן לממש בכמה דרכים שונות. שאלה 1. S קבוצה עם לכל היותר n איברים ( n נתון).
E N D
תרגול 4 ADTs: Array, Queue, Stack,Linked List
ADT – מבנה נתונים אבסטרקטי דוגמאות:
ADT – מבנה נתונים אבסטרקטי דוגמאות:
ADT – מבנה נתונים אבסטרקטי דוגמאות: הערה חשובה: מבני גישה אבסטרקטיים ניתן לממש בכמה דרכים שונות.
שאלה 1 • S קבוצה עם לכל היותר n איברים (n נתון). • לכל איבר יש מפתח בתחום [0…n-1], ואין שני איברים עם אותו מפתח. • מצאו מבנה נתונים בגודל O(n) התומך בפעולות הבאות בזמנים הנתונים:
שאלה 1 • פתרון: בעזרת מיון ישיר (מערך) COUNT = 0 . . . Init (n) for (i=0 ; i<n ; i++) A[i] = null; count = 0; Null Null Null Null Null Null . . .
שאלה 1 • פתרון: בעזרת מיון ישיר (מערך) COUNT = 0 COUNT = 1 . . . isElement (k) return (A[k] != null); Null X k-1 Null k Null Key= k k+1 Null Insert (x) If(!isElement (x.key){ A[x.key] = x; count++; } Null Null . . .
שאלה 1 • פתרון: בעזרת מיון ישיר (מערך) isEmpty () return (count == 0); Remove (k) If(isElement (k){ A[k] = null; count--; } hasAll () return (count == n);
שאלה 2 שאלה: הציעו כיצד לממש תור בעזרת 2 מחסניות. פתרון: x a b c d
שאלה 2 שאלה: הציעו כיצד לממש תור בעזרת 2 מחסניות. פתרון: Enqueue (x) moveElements(A,B); A.Push(x); moveElements(B,A); Dequeue( ) element = A.Pop(); return element; isEmpty ( ) return A.isEmpty(); moveElements(X,Y) while (! X.isEmpty()) { temp = X.Pop(); Y.Push(temp) ; }
שאלה 2 שאלה: הציעו כיצד לממש תור בעזרת 2 מחסניות. פתרון נוסף: Enqueue (x) A.Push(x); Dequeue( ) moveElements(A,B); element = B.Pop(); moveElements(B,A); return element; isEmpty ( ) return A.isEmpty(); moveElements(X,Y) while (! X.isEmpty()) { temp = X.Pop(); Y.Push(temp) ; }
שאלה 2 שאלה: הציעו כיצד לממש תור בעזרת 2 מחסניות. פתרון נוסף נוסף: isEmpty ( ) return ( A.isEmpty() && B.isEmpty()); moveElements(X,Y) while (! X.isEmpty()) { temp = X.Pop(); Y.Push(temp) ; } Enqueue (x) A.Push(x); Dequeue( ) If (B.isEmpty()) moveElements(A,B); element = B.Pop(); return element;
שאלה 2 שאלה: הציעו כיצד לממש תור בעזרת 2 מחסניות. פתרון: Enqueue (x) moveElements(A,B); A.Push(x); moveElements(B,A); Dequeue( ) element = A.Pop(); return element; isEmpty ( ) return A.isEmpty(); moveElements(X,Y) while (! X.isEmpty()) { temp = X.Pop(); Y.Push(temp) ; }
שאלה 3 שאלה: נתונות 2 רשימות מקושרות חד-כיווניות L1,L2 עם זנב משותף באורך k, ורישות לא משותפות באורכים n וm. הראו כיצד ניתן למצוא את הקודקוד המשותף הראשון בזמן O(m+n+k). דוגמא: m = 4 k = 3 Null Head 2 n = 2 Head 1
שאלה 3 שאלה: נתונות 2 רשימות מקושרות חד-כיווניות L1,L2 עם זנב משותף באורך k, ורישות לא משותפות באורכים n וm. הראו כיצד ניתן למצוא את הקודקוד המשותף הראשון בזמן O(m+n+k). פתרון: • מוצאים את האורך של L1,L2 • ברשימה הארוכה, זזים קדימה את ההפרש • כעת המרחק מהקודקוד המשותף שווה ב2 הרשימות. כל עוד הרשימות לא התאחדו (קודקוד ראשון משותף), זזים קודקוד 1 קדימה בשתי הרשימות.
שאלה 3 פתרון: • מוצאים את האורך של L1,L2 • ברשימה הארוכה, זזים קדימה את ההפרש • כעת המרחק מהקודקוד המשותף שווה ב2 הרשימות. כל עוד הרשימות לא התאחדו (קודקוד ראשון משותף), זזים קודקוד 1 קדימה בשתי הרשימות. הדגמת הפתרון: m = 4 k = 3 Null Head 2 n = 2 Head 1
שאלה 3 פתרון: • מוצאים את האורך של L1,L2 • ברשימה הארוכה, זזים קדימה את ההפרש • כעת המרחק מהקודקוד המשותף שווה ב2 הרשימות. כל עוד הרשימות לא התאחדו (קודקוד ראשון משותף), זזים קודקוד 1 קדימה בשתי הרשימות. הדגמת הפתרון: Current Current Current Current Current Current Current Current Null Head 2 Current Current Current Current Current Current Head 1 Length1 = 7 Length2 = 5
שאלה 3 פתרון: • מוצאים את האורך של L1,L2 • ברשימה הארוכה, זזים קדימה את ההפרש • כעת המרחק מהקודקוד המשותף שווה ב2 הרשימות. כל עוד הרשימות לא התאחדו (קודקוד ראשון משותף), זזים קודקוד 1 קדימה בשתי הרשימות. הדגמת הפתרון: Current 1 Current 1 Current 1 Null Head 2 Current 2 Head 1 Length1 – Length2 = 2
שאלה 3 פתרון: • מוצאים את האורך של L1,L2 • ברשימה הארוכה, זזים קדימה את ההפרש • כעת המרחק מהקודקוד המשותף שווה ב2 הרשימות. כל עוד הרשימות לא התאחדו (קודקוד ראשון משותף), זזים קודקוד 1 קדימה בשתי הרשימות. הדגמת הפתרון: Current 1 Current 1 Current 1 Null Head 2 Current 2 Current 2 Current 2 Head 1
שאלה 4 שאלה: בהינתן רשימה חד-כיוונית, הציעו דרך בה ניתן לטייל קדימה ואחורה ברשימהבזמן O(1), ע"י תוספת זכרון של O(1) בלבד פתרון: אי-אפשר להפוך את הרשימה לדו-כיוונית - זה O(n) זיכרון • נשתמש ב2 מצביעים – current וprev שיצביעו על האיבר הנוכחי וזה שבא לפניו • כשנזוז קדימה ברשימה, נפנה ברשימה את המצביעים אחורה • כשנזוז אחורה ברשימה, נחזיר את המצביעים קדימה
שאלה 4 - הדגמה moveBackward() temp=current; current=prev; prev=prev.next; current.next=temp; init() current=head; prev=null; moveForward() temp = prev; prev=current; curent=current.next; prev.next=temp; temp = prev; prev=current; curent=current.next; prev.next=temp; prev current Head Temp
איחוד 3+4 (אם יש זמן) שאלה: נתונות 2 רשימות מקושרות חד-כיווניות עם זנב משותף באורך k, ורישות לא משותפות באורכים n וm. הציעו דרך למצוא את הקודקוד המשותף הראשון של 2 הרשימות, בזמן שאינו תלוי בk. ( הניחו m,n>0 וכן k>>m,n ) מה הזמן והמקום שדורש הפתרון שהצעתם דורש?
שאלה 5 שאלה:A מטריצה בוליאנית (ערכי 0 או 1) בגודל nXn. תארו מבנה נתונים שתומך בפעולות הבאות בזמנים הנתונים:
שאלה 5 פתרון: • נשמור, בנוסף למטריצה, גם מערך Sum, שמכיל את סכום האיברים בשורות. כלומר, Sum[i] = מספר האחדות בשורה ה-i. • בנוסף, נשמור 2 מונים של מספר השורות המלאות ומספר השורות ללא אחדות כלל.
שאלה 5 פתרון: • נשמור, בנוסף למטריצה, גם מערך Sum, שמכיל את סכום האיברים בשורות. כלומר, Sum[i] = מספר האחדות בשורה ה-i. • בנוסף, נשמור 2 מונים של מספר השורות המלאות ומספר השורות ללא אחדות כלל. • הדגמה: Flip(2,3); COUNT_0 = 1 COUNT_1 = 1
שאלה 5 פתרון: • נשמור, בנוסף למטריצה, גם מערך Sum, שמכיל את סכום האיברים בשורות. כלומר, Sum[i] = מספר האחדות בשורה ה-i. • בנוסף, נשמור 2 מונים של מספר השורות המלאות ומספר השורות ללא אחדות כלל. • הדגמה: Flip(2,3); COUNT_0 = 1 COUNT_1 = 2
שאלה 5 flip(i,j) if (A[i][j]==0) { A[i][j]=1; if (Sum[i]=0) count0- -; Sum[i]++; if (Sum[i]=n) count1++; } else { A[i][j]=0; if (Sum[i]=n) count1- -; Sum[i]--; if (Sum[i]=0) count0++; } קוד: init() fill A with 1’s fill Sum with n. count1=n count0=0 hasRowOf1() return count1>0 hasRowOf0() return count0>0
שאלה 7 נגדיר "מחסנית מינימום" כמבנה נתונים התומך בפעולות הבאות: • Create()– אתחול מבנה הנתונים. • Insert(x)– הכנסת איבר x למבנה. • RemoveLast()– הוצאת האיבר שהוכנס אחרון. • Min()– החזרת הערך של האיבר הקטן ביותר במבנה (ללא הוצאתו). • ChangeMin(k)– שינוי ערך האיבר הקטן ביותר במבנה ל – k. הנחה: כל האיברים שונים זה מזה. הציעו מימוש ל"מחסנית מינימום", כאשר סיבוכיות הזמן הנדרשת לארבע הפעולות הראשונות היא O(1), וסיבוכיות הזמן הנדרשת ChangeMin היא O(t), כש– t הינו מספר האיברים במבנה שהוכנסו אחרי האיבר המינימלי (הכוונה לאיבר המינימלי לפני שהפעולה ChangeMin בוצעה).
שאלה 7 נגדיר "מחסנית מינימום" כמבנה נתונים התומך בפעולות הבאות: • Create()– אתחול מבנה הנתונים. • Insert(x)– הכנסת איבר x למבנה. • RemoveLast()– הוצאת האיבר שהוכנס אחרון. • Min()– החזרת הערך של האיבר הקטן ביותר במבנה (ללא הוצאתו). • ChangeMin(k)– שינוי ערך האיבר הקטן ביותר במבנה ל – k. הנחה: כל האיברים שונים זה מזה. פתרון: • נשתמש ברשימה דו-כיוונית • בנוסף, כל רשומה תכיל מצביע לערך המינימלי מבין הערכים הוותיקים יותר (כולל האיבר עצמו)
שאלה 7 פתרון: • נשתמש ברשימה דו-כיוונית • בנוסף, כל רשומה תכיל מצביע לערך המינימלי מבין הערכים הוותיקים יותר (כולל האיבר עצמו) הדגמה: head 5 7 3 15 10 6
שאלה 7 פתרון: • נשתמש ברשימה דו-כיוונית • בנוסף, כל רשומה תכיל מצביע לערך המינימלי מבין הערכים הוותיקים יותר (כולל האיבר עצמו) הדגמה: אם נבצע ChangeMin(12), כיצד ישתנו החיצים? head 5 7 12 15 10 4
שאלה 7 פתרון: • נשתמש ברשימה דו-כיוונית • בנוסף, כל רשומה תכיל מצביע לערך המינימלי מבין הערכים הוותיקים יותר (כולל האיבר עצמו)