תרגול מס' :1 מבני נתונים – מבוא כללי • • • • מבנה נתונים – דרך לארגן נתונים במחשב ולגשת אליהם. בקורס זה נלמד על מבני נתונים שונים אשר משמשים לבניית אלגוריתמים יעילים למגוון בעיות .בבואנו לתכנן אלגוריתם הדורש פעולות על קבוצות נרצה להשתמש במבנה נתונים המתאים לנו מבחינת סוג הפעולות אשר הוא תומך בהן ,ומבחינת יעילות (זמן ריצה ,מקום בזיכרון). מבני נתונים הידועים לנו עד כה :מערכים ,עצים ,תורים ,מחסניות, רשימות .למשל כאשר רצינו לבצע חיפוש יעיל על קבוצת מספרים השתמשנו במערך ממוין והפעלנו עליו חיפוש בינרי. החומר התיאורטי יוצג בהרצאות ,כאשר בתרגולים נתרכז בפתרון בעיות בעזרת מבנים שונים. הצורך במבני נתונים: • מאפשרים תכנון ומימוש של בעיות מורכבות. • בעזרתם ניתן ללמוד על תכונות שונות של הקבוצה ,תכונות לא בולטות לעין. • תכנון נכון יכול להביא לכתיבת תכניות באופן פשוט ,יעיל ומדויק (ראה דוגמא ). דוגמה • שני אנשים Sו Yקיבלו עבודה בתור מזכירים .במסגרת העבודה כל אחד אחראי על ארון תיקים אישיים .סדר יומו של Sבהינתן תיק אישי חדש היה פשוט לזרוק את התיק לתוך המגירה .סדר יומו של Yבהינתן תיק אישי חדש היה להכניסו למקומו לפי סדר אלף-בית. כמה זמן עבד כל אחד מהם? ל Sהעבודה הייתה מאוד פשוטה ,למעשה הוא לא עבד בכלל! לעומתו Yהיה צריך למצוא את מיקומו של התיק החדש ורק אז להכניסו למקום! האם העבודה של Sיעילה יותר? התשובה לשאלת היעילות תלויה בהמשך .אם בזה סיימנו את העבודה ,אז עבודת Sיעילה יותר! • • • • • • • • אבל מה אם יבקשו תיק מתוך האוסף? איזה עבודה תהיה יעילה יותר? ברור ש Yיוכל לשלוף את התיק מהר יותר! ומה היה קורה אם היו מבקשים תיק לפי מספר ת.ז?. במקרה זה לא יהיה הבדל! כל זאת בכלל בלי להתייחס למקום. איזה צורת ארגון דורשת יותר מקום? Sיכול להשתמש במגירה אחת גדולה עבור כל התיקים. אינטואיטיבית נראה ש Y -צריך יותר מקום (חוצצים או מגירה לכל אות) .אך האם זה באמת נחוץ? הנקודה החשובה בדוגמה זו היא שיעילות נקבעת לפי צורת ארגון הנתונים .צורת הארגון ,אם היא מתוכננת כראוי ,צריכה להיות מותאמת לסוג הבעיה .בקורס זה ,נרצה לחקור את צורות הארגון השונות כדי שבבוא העת נוכל להתאים מבנה נכון לכל בעיה. זמן הריצה של אלגוריתם הוא הערכה ,באמצעות חסמים ,על מספר הפעולות האטומיות שמבצע האלגוריתם במהלך פעולתו, כפונקציה של גודל הקלט (.)n אין בוחנים את זמן הריצה ביחידות זמן (שניות ,דקות וכו') ,שכן משך הזמן לביצוע פעולות משתנה מסביבת ריצה אחת לשנייה ,אלא ביחידות מדידה מוחלטות (כגון ,מספר פעולות ו/או מספר פעולות השוואה) .לכן ,נוטים להתעלם מקבועים בעת התייחסות לזמן ריצה של אלגוריתם. פעולות יסוד (אטומיות) :השמה ,פעולה מתמטית ,פעולת השוואה וכו' Question 1 • An array of n elements is given, how many comparisons between elements in the array are needed in order to find the maximum element? Solution: • FindMax(A) • n ← size(A) • max ← A[0] • for i ← 1 to n-1 • if A[i] > max then • max ← A[i] The for-loop is executed n-1 times, in each ‘max’ is compared to the next element in A, thus the number of comparisons is n-1. Question 2 • An array of n elements is given, how many comparisons between two elements in the array are needed in order to find both the largest and the second largest number? Solution 1: Execute the algorithm described in question 1 twice. Thus n-1 comparisons are needed in order to find the largest and n-2 in order to find the second largest. Find2Largest(A) n ← size(A) max1 ← A[0] index ← 0 //index of maximum for i ← 1 to n-1 then if A[i] > max1 max1 ← A[i] index ← i A' ← A - A[index] max2 ← A'[0] for i ← 1 to n-2 if A'[i] > max2 max2 ← A'[i] • The first for-loop is executed n-1 times and the second is executed n-2 times. Total = n-1 + n-2 = 2n - 3 Solution 2: • We build a tournament tree. We place all the n elements in the leaves and as in tennis tournament, in each round several pairs “play” against each other and only the larger element of each pair make it to the next round. The winner is the largest one, and the second largest is the largest among the elements who “competed” against the winner, there are log2 n such elements. Example The largest element is 'max' The second largest element is max{ x1, x2, x3 } Number of comparisons • Finding the largest: n/21 + n/22 + n/23 + ... + n/2k = n/2 + n/4 + n/8 + ... + 1 = n-1 . • Finding the second largest: Use the algorithm shown in question 1 to find the largest among the (log2 n) numbers who "competed" against the maximum, thus (log2 n - 1) comparisons are needed. • If we sum (1) and (2): n - 1 + log n - 1 = n + log2 n - 2 (instead of 2n – 3) Question 3 • What will be the value of k after each execution of the following code section? • Provide a rough approximation on the runtime of the following code sections (disregarding constants). a. k ← 0 for i ← 1 to n k++ b. k←0 for i ← 1 to n for j ← 1 to n k++ c. k←0 for i ← 1 to n for j ← 1 to i k++ Solution: • a. The loop is executed n times, each time k is incremented. k=n runtime ≈ n b. The main loop is executed n times. The inner loop is executed n times for each execution of the main loop, in each execution k is incremented. k=n2 runtime ≈ n2 c. The main loop is executed n times. The inner loop is executed i times for the i’th iteration of the main loop, in each execution k is incremented. k =1+2+…+n= runtime ≈ n2 n(n 1) 2 Question 4 • What is the number of multiplications in the following code? • Provide a rough approximation on the runtime of the following code (disregarding constants). k←1 while (k < n) k←k*2 Solution: • Let i be the number of loop executions. • The loop ends when 2i ≥ n, thus executed ⌈ log2 n ⌉ times, each time k is multiplied once. Number of multiplications: ⌈ log2 n ⌉ Runtime ≈ log2 n Question 5 • What is the number of multiplications in the following code. • Provide a rough approximation on the runtime of the following code (disregarding constants). for i ← 1 to n k←1 while (k < i) k ← k*2 Solution: • The while-loop is executed ⌈ log2 i⌉ times for each i ( i = 1..n), each time k is multiplied by two exactly once, therefore the number of multiplications is: • ⌈ log 1 ⌉ + ⌈ log 2 ⌉ + ⌈ log 3 ⌉ + … + ⌈ log2 n ⌉≈ • log2 1 + log2 2 + log2 3 + … + log2 n = log2(1*2*3*…*n) = log2 (n!) • Consequently, the runtime is roughly log2(n!). Question 6 • Evaluate the number of multiplications in the following code (assume that n=2k): my_power( x, n) if (n=0) return 1 if (n=1) return x return my_power(x, n/2)*my_power(x, n/2) • How can we reduce this number? Solution: • The number of multiplications equals to the number of the inner nodes in the recurrence tree: • 1+2+4+8…+n/2 = n-1 Improvement • Evaluate the number of multiplications in the following code: my_power( x, n) if (n=0) return 1 if (n=1) return x temp ← my_power(x, n/2) return temp*temp Solution: • For each recursive call of the improved function my_power, we have only one new recursive call (and not two as in the previous code). So, the recurrence tree becomes a path of length log n (every node has only one child). As we saw before, the number of multiplications equals to the number of inner nodes in the recurrence tree, that is for the improved code, log n – 1 Question 7 • Describe an algorithm that, given a sorted array A of n integers and an integer x, determines whether or not there exist two elements in A whose sum is exactly x, by doing at most 3n comparisons between elements. Solution: • TwoSum(A, x) p←0 q ← n-1 while (p < q) if (A[p]+A[q] = x) return "Yes" else if (A[p]+A[q] < x) p++ else q-return "No" Solution: • At each iteration of the while loop, either p is incremented or q is decremented. Hence the number of iterations is bounded by n-1, in every iteration we do at most 3 comparisons (one to check the condition of the while loop, and two more inside the loop). Example: • x = 25, A = 1 5 6 7 p current sum: 32 10 11 12 20 30 31 q Example: • x = 25, A = 1 5 6 7 p current sum: 31 10 11 12 20 30 q 31 Example: • x = 25, A = 1 5 6 7 p current sum: 21 10 11 12 20 q 30 31 Example: • x = 25, A = 1 5 p • Return "Yes". 6 7 10 11 12 20 q 30 31 שאלה 8 • נתון מערך Aובו nמספרים .הראה כיצד ניתן למצוא את המינימום ואת המקסימום של Aבאמצעות לא יותר מאשר 3n/2השוואות. פתרון: • הרעיון :נחלק את המספרים לזוגות ,בכל זוג נשים את המספר הקטן ב – A1ואת הגדול ב – ,A2כך מובטח כי המינימום והמקסימום של ,Aהם המינימום והמקסימום של A1ו – A2 בהתאמה. • Min_and_Max(A,n) • A1[n/2],A2[n/2] • for i←1 to n/2 if (A[i] < A[i + n/2]) A1[i] ← A[i] A2[i] ← A[i + n/2] השוואותn/2 else A1[i] ← A[i + n/2] A2[i] ← A[i] min ← A1[1] max ← A2[1] for i=2 to n/2 if (A1[i] < min) השוואותn/2-1 min ← A1[i] if (A2[i] > max) השוואותn/2-1 max ← A2[i] • אם nהוא אי-זוגי ,אפשר להכניס את האיבר האחרון של ,Aגם ל – 𝑛−1 𝑛 𝑛 A1וגם ל – A2ולקבל שמספר ההשוואות הוא + + 1 − 1 + 3𝑛−1 2 = ,+ 1 − 1כלומר עדיין פחות מ - 𝑛3 2 2 השוואות. 2 2