Professional Documents
Culture Documents
הרצאה שניה :מערכים ,מטריצות
דלילות ,ורשימות מקושרות
אורי רוטנשטרייך
רועי אנגלברג
השקפים הוכנו ע״י פרופ׳ ארז פטרנק
)Chapter 11.2– Linked lists (204 – 213
1
מערך )כמבנה נתונים אבסטרקטי(
העיקרון :אוסף איברים הנגישים לפי אינדקס
מערך מכיל אוסף של איברים וקבוצת אינדקסים ;Iמערך תומך בפעולות הבאות:
.1הפעולה ) create(type,Iמחזירה מערך של איברים מטיפוס typeעם
אינדקסים בקבוצה .I
.2הפעולה ) store(A,i,eמוסיפה את איבר eמטיפוס typeעם אינדקס iלאברי
המערך )
.( i 2 I
קיצור מקובל לפעולה זו. A[i] = e :
.3הפעולה ) get(A,iמחזירה את האיבר שהוכנס למערך אחרון עם פקודת
storeשהשתמשה באינקס
.i
קיצור מקובל לפעולה זו. A[i] :
3
מימושים של מערך
)נניח אינדקסים שלמים ורצופים(
4
מימוש שני
מספר איזורים רצופים בזיכרון שלכל אחד גודל
קבוע .n
base
למה זה מועיל?
5
מערך דו-מימדי
;]int A[m][n
p=a[k];
for (j=k-1; j>=0; j--)
p = p⋅x + a[j]
addr=i[d];
for (j=d-1; j>=1; j--)
addr = addr*n[j] + i[j];
addr= base + addr;
אופציה ב אופציה א
⋮ ⋮ ⋮
© cs, Technion 9
לוקליות של גישה לזכרון
• איזו פעולה?
• איך נפתור את זה?
בדוגמא זוV[0]=5, V[1]=3, V[4]=7 :
0 212
5
212 131
2
0 131 4 0
if (is_initialized(i)) אחזר
return A[i]; get(V,i):
else
return constant;
if (!is_initialized(i)) { שמור
C[top] = i ; store(V,I,e):
B[i] = top ;
top = top +1;}
A[i]= e;
תחתון:
חצי מערך
20
רשימות מקושרות
נזכיר כעת כיצד מתבצע חיפוש ,הכנסה ,והוצאהfind, insert, delete :
ברשימות מקושרות ונגדיר וריאציות עליהן.
head 7 2 5
t
© cs, Technion 22
הכנסת איבר לרשימה מקושרת
int insert ( NODE *t, DATA_TYPE x){ פעולת הכנסה
NODE *p; insert(t,x):
if (t == NULL) return 0;
p = (NODE *) malloc (sizeof (NODE)); מצביע לצומתt הפרמטר
p → info = x; שאחריו מוסיפים צומת
p → next = t → next ; .חדש
t → next = p ;
return 1;
}
head 7 2 5
t 6
© cs, Technion 23
הוצאת איבר מרשימה מקושרת
{)delete ( NODE *t פעולת הסרה
; NODE * temp delete(t):
*/מצביע לצומת שמורידים*temp = t → next; /
הפרמטר tמצביע
; t → next = temp → next
לצומת שלפני
; )free (temp
הצומת
}
שמוציאים.
t 6
temp
© cs, Technion 24
הוצאת איבר מראש רשימה מקושרת
int delete_first ( NODE **p_head){ פעולת מחיקת צומת ראשון
NODE * temp ; delete_first(r):
if (*p_head == NULL) return 0 ;
temp = *p_head;
*p_head = temp → next ;
free (temp) ;
return 1; /* success code
*/
}
head 7 2 5
p_head
? איך נמנעים מכך.קוד מיוחד עבור האיבר הראשון זה מסורבל
© cs, Technion 25
רשימות עם כותרת
מוסיפים איבר "ריק" בתחילת הרשימה )נקרא לרוב ”.(“dummy node
תוספת זו חוסכת:
• קוד מיוחד לרשימות ריקות.
• קוד מיוחד להסרת הצומת הראשון.
• קוד מיוחד להכנסה לפני הצומת הראשון.
בייצוג זה רשימה בת שתי איברים מיוצגת כך:
head 2 5
1
© cs, Technion 26
רשימות מעגליות
2 5
7
יתרונות:
.1אפשר להגיע מכל איבר לכל איבר.
element1 .2ניתן לשרשר רשימות מעגליות בזמן קבוע,
בהינתן מצביעים לאיבר אחד בכל רשימה.
temp
t
יתרונות:
• מאפשר להגיע מכל איבר לכל איבר
• מאפשר להוציא איבר בהינתן מצביע tאליו )ולא רק את האיבר
שאחריו(.
; t → next → prev = t → prev
; t → prev → next = t → next
t
© cs, Technion 28
הוצאה “טריקית" ברשימה רגילה
האם ניתן להוציא איבר אליו מצביע tגם מרשימה חד-כיוונית ?
t
פשוט נעתיק את האינפורמציה בתא העוקב ל t-לתא ש t-מצביע אליו
ונוציא את התא העוקב.
t
חסרונות:
• לא עובד עבור האיבר האחרון
• יתכן ויש מצביעים נוספים לתא שהוצא ) (8ואין אפשרות לעדכן מצביעים אלה
• יתכן שיש מצביעים נוספים לתא ששינינו ) (5והם מצפים עדיין לראות שם את 5
• צומת יכול להכיל הרבה אינפורמציה ולכן העתקה עלולה להיות ארוכה
© cs, Technion 29
דוגמאות לשימושים ברשימות
30
ייצוג פולינומים דלילים
0.3x1000 + 4.5x2 + 0.1 נעלם אחד .דוגמא:
מקדם חזקה
מימוש זה יעיל כאשר ההפרש בין החזקה הגבוהה והנמוכה גדול וכן הרבה
מקדמים של חזקות הביניים מתאפסים.
4
column
0
row value next
1
2
down
3
4
© cs, Technion 32
כפל מטריצות דלילות
#define N_row 20
#define N_col 20
NODE *row_header[N_row],
*col_header[N_col];
/* Compute the value of c[i][j] */
float mult_row_col(int i, int j){
float c = 0 ;
NODE *r = row_header[i],
*k = col_header[j];