חזור לתיקייה: 02340218 - מבני נתונים 1

2 - מבני נתונים בסיסיים (ממתמ)

חיפוש בתיקיה
Ctrl K
לחץ כאן או הקש Ctrl K כדי לחפש בכל התיקיה
  • מערך
  • מערך רב מימדי
  • אתחול מערך ב-O(1)
  • מטריצות

2 - מבני נתונים בסיסיים (ממתמ)

02340218

מבני נתונים 1

רשימות הרצאה לקריאה בשבת

מבני נתונים בסיסיים (ממתמ)

הופק מתוך תקיית התואר של שקד

uni-folder.vercel.app

מערך

הגדרה 1 (מערך)

טיפוס נתונים אבסטרקטי המכיל אוסף של איברים וקבוצת אינדקסים III ותומך בפעולות הבאות:
א. create(type,I)create(type, I)create(type,I) - מחזירה מערך של איברים מטיפוס typetypetype עם אינדקסים בקבוצה III.
ב. store(A,i,e)store(A,i,e)store(A,i,e) - מוסיפה איבר eee מטיפוס typetypetype עם אינדקס iii (כאשר i∈Ii \in Ii∈I) לאיברי המערך.
ג. get(A,i)get(A,i)get(A,i) - מחזירה את האיבר האחרון שהוכנס עם פקודת storestorestore לאינדקס iii.

נוכל לממש מערך בכמה דרכים:

  1. איזור רצוף בזכרון: זמן ביצוע store,getstore,getstore,get הוא O(1)O(1)O(1) וזמן יצירת מערך חדש תלוי בזמן הקצאת מקום ובשאלה האם צריך למלא את כולו בערך התחלתי בעת היצירה.
  2. מספר איזורים רצופים בזכרון שלכל אחד גודל קבוע kkk: לכל איזור כזה נקרא "בלוק". כדי לממש מערך בגודל nnn יש להקצות mmm בלוקים כאשר m=⌈nk⌉m=\lceil \frac{n}{k}\rceilm=⌈kn​⌉ ובלוק נוסף שנקרא "מדריך". נסמן את כתובת הבסיס של המדריך ב-basebasebase ואז האיבר ה-A[i]A[i]A[i] נמצא בכתובת base[⌊ik⌋]+i ⁣ ⁣ ⁣(mod  k)base\left[ \lfloor \frac{i}{k} \rfloor \right]+i\pmod{k}base[⌊ki​⌋]+i(modk). זמן חישוב הכתובת במקרה זה הוא גם כן O(1)O(1)O(1).
    לדוגמה, עבור k=6,i=16k=6,i=16k=6,i=16 הכתובת של A[16]A[16]A[16] מחושבת ע"י: base[⌊166⌋]+16 ⁣ ⁣ ⁣(mod  6)=base[2]+4base\left[ \lfloor \frac{16}{6} \rfloor \right]+16\pmod{6}=base[2]+4base[⌊616​⌋]+16(mod6)=base[2]+4.

מערך רב מימדי

במערך רב מימדי A[nd]…[n3][n2][n1]A[n_{d}]\dots[n_{3}][n_{2}][n_{1}]A[nd​]…[n3​][n2​][n1​] הכתובת של A[id]…[i2][i1]A[i_{d}]\dots[i_{2}][i_{1}]A[id​]…[i2​][i1​] מחושבת ע"י הנוסחה:

base+idnd−1⋯n1+id−1nd−2⋯n1+⋯+i1base+i_{d}n_{d-1}\cdots n_{1}+i_{d-1}n_{d-2}\cdots n_{1}+\dots+i_{1}base+id​nd−1​⋯n1​+id−1​nd−2​⋯n1​+⋯+i1​ =base+((…((idnd−1+id−1)nd−2+id−2)+nd−3+⋯+i3)n2+i2)n1+i1=base+{\LARGE(}{\Large(}\dots{\large(}(i_{d}n_{d-1}+i_{d-1})n_{d-2}+i_{d-2}{\large )}+n_{d-3}+\dots+i_{3}{\Large )}n_{2}+i_{2}{\LARGE)}n_{1}+i_{1}=base+((…((id​nd−1​+id−1​)nd−2​+id−2​)+nd−3​+⋯+i3​)n2​+i2​)n1​+i1​

נוכל לייעל את חישוב הכתובת באמצעות הקוד הבא:

addr = i[d];
for (j = d - 1; j >= 1; j--)
	addr = addr * n[j] + i[j];
addr = base + addr;

אתחול מערך ב-O(1)O(1)O(1)

נרצה לעדכן את פעולת createcreatecreate כך שתקבל פרמטר נוסף ddd כך שכל התאים במערך יאותחלו לערך זה.
אתחול מערך באופן זה בגודל nnn דורש זמן של Θ(n)\Theta(n)Θ(n) אך נרצה לעשות זאת בפעולת האתחול בזמן קבוע.
⟸ כדי לעשות זאת אנו נשתמש בזכרון נוסף (ללא שינוי אסימפטוטי).

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

מטריצות

  • עבור מטריצה סימטרית נוכל לאחסן רק את חצי מהערכים שכן Ai,j=Aj,iA_{i,j}=A_{j,i}Ai,j​=Aj,i​. נחשב את המיקום כך:
    Add(i,j)={Base+ii+12+ji≥jAddr(j,i)elseAdd(i,j)=\begin{cases} Base+i \frac{i+1}{2}+j & i\geq j \\ Addr(j,i) & else \end{cases}Add(i,j)={Base+i2i+1​+jAddr(j,i)​i≥jelse​
  • עבור מטריצטת דלילות, כשרוב המוחלט של האיברים הוא 000, נוכל לשמור במערך את האיברים של המטריצות בשלשות (i,j,Aij)(i,j,A_{ij})(i,j,Aij​).
הגדרה 2 (סדרת מטריצות דלילה)

אם סדרת מטריצות M1,…,MnM_{1},\dots,M_{n}M1​,…,Mn​ מקיימת שמספר האיברים השונים מקבוע ccc הוא מסדר גודל של o(m(n))o(m(n))o(m(n)) כאשר m(n)m(n)m(n) הוא מספר המקומות המקסימלי במטריצה MnM_{n}Mn​ אז זוהי סדרה של מטריצות דלילות ותקרא דלילה.

דוגמה

מטריצות אלכסוניות

כאשר נרצה לאחסן סדרה שכזו נשמש בטריק של אחסון שלשות (i,j,Ai)(i,j,A_{i})(i,j,Ai​) בסדר לקסיקוגרפי. בכך, נוותר על סיבוכיות הזמן O(1)O(1)O(1) לטובת חוסך בזכרון והאצה של םעולות חיבור וכפל.