Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבני נתונים מופשטים בסיסיים

Similar presentations


Presentation on theme: "מבני נתונים מופשטים בסיסיים"— Presentation transcript:

1 מבני נתונים מופשטים בסיסיים
רשימה: n = רשימה ריקה משמעויות: ראשון: אחרון: מקום: לפני מבנה נתונים: L:LIST P:POSITION המקום האחרי-אחרון: (END(L פעולות: יתכנו הרבה אנחנו מעניינים בישום השמטת כפולים צריך: מציאת ראשון, סריקה, קריאה, השמטה.

2 פעולות 1. INSERT (x, p, L) אם יש p ברשימה: a1, a2,…..,ap-1, x, ap,….,an אם (p=END(L : a1, a2,…..,an,x אחרת: Undefined 2. LOCATE(x, L) מקום ראשון של .x אם לא מופיע: (END(L 3. RETRIEVE (p,L) מוגדר רק אם p נמצא ב - L. 4. DELETE(p,L) a1, a2,…..,an a1, a2,…..,ap-1,ap+1,….,an מוגדר רק אם p ב -L. 5. NEXT(p,L), PREVIOUS(p,L) מוגדר טבעי 6. MAKENULL(L) 7. FIRST(L)

3 יישום השמטת כפולים Procedure PURGE (Var L:LIST) Var p,q: Position
{p = Current, q = Search} begin (1) p:= FIRST(L) (2) while p<>END[L] do begin (3) q:= NEXT(p,L) (4) while q<>END(L) do (5) if same (RET(p,L), RET(q,L)) (6) then DELETE(q,L) (7) else (8) q:= NEXT(q,L) (9) p:= NEXT(p,L) end; end; {PURGE} q אינו מקודם כי הרשימה התכווצה

4 יישומים של מבנה הנתונים
מערך, רשימה מקושרת, (סמנים) יישום במערך 1st element 2nd “ Last element ריק רשימה Maxlength last Const maxlength = 99 type LIST = record elements: array[1..maxlength] of element type; last: integer end; Position: integer; function END(var L:LIST): Position begin return(L.Last+1)

5 יישום ברשימה מקושרת (רגילה)
LIST header a1 a2 an POS1 POS3 POS2 POS.END(L) כל תא מורכב מ: - ערך האיבר מצביע לאיבר הבא מימוש עם מצביעים

6 הגדרת הרשימה: type celltype = record element: elementtype;
next:celltype; end LIST = celltype Position = celltype

7 בצוע לא יעיל : (צריך לרוץ על כל הרשימה) END[L] Function END (L:LIST) : position ; {returns a pointer to the last cell of L } Var q: position begin q:= L ; while q . next < > nil do q:= q  . next ; return (q) ; end ; (END)

8 יישום רשימה באמצעות סמנים
(CURSORS) שימוש באינדקסים (בתוך מערך) במקום מצביעים. 1 2 3 4 5 6 7 8 9 10 element next H L R מאחסנים כמה רשימות ( + רשימת פנויים) אחרון מצביע על 0. ריקה - כששם האחרון מצביע על 0.

9 דוגמה: 5 1 9 L: y, e, s R: n, o Avail: 9, 10, 11, 6, 2, 4
3 4 5 6 7 8 9 10 11 n - s y o e 5 L 1 R 9 Avail L: y, e, s R: n, o Avail: 9, 10, 11, 6, 2, 4 הוספת והשמטת איברים DELETE INSERT (מרשימת הפנויים) צריך MOVE .

10 שים לב: כמו ברשימות מקושרות התייחסותנו לתא היא דרך המצביע עליו!!!!
ביצוע הזזה שים לב: כמו ברשימות מקושרות התייחסותנו לתא היא דרך המצביע עליו!!!! העברת התא “p” לפני התא “q”: 3 p q 4 2 1 temp התא ש- p מצביע עליו יזוז לפני התא ש-q מצביע עליו. שיטה: (לא לאבד תאים!) א) לסמן ב temp ב) להעביר סמנים שניתן לשחרר.

11 השוואת יישומים קריטריון מערך מקושרת סמנים קריטריון
קריטריון מערך מקושרת סמנים גודל מקסימלי מוגבל “לא מוגבל” מוגבל/בסה”כ INS/DEL O(N) O(1) O(1) PREVIOUS O(1) O(N) O(N) END O(1) “O(N)” “O(N)” Position ישיר משתנה (יחסי) משתנה (יחסי) נצילות מקום מבוזבז “לא מבוזבז” מבוזבז “פחות” דרישת מקום מקום * 1 מקום + מצביעים מקום + סמנים קריטריון גודל מקסימלי INS/DEL PREVIOUS END Position נצילות מקום דרישת מקום

12 רשימה מקושרת כפולה מגבלות מקושרת רגילה: 1. מציאת סוף (END(L
2. מציאת קודם PREVIOUS (ללכת הפוך) פתרון: מקושרת כפולה X Y Z type celltype = record element: elementtype; next, previous:celltype; end ; Position = celltype פשטות ביצוע DELETE

13 יישום התחלה וסוף: אפשרות א’: איבר ראשון ואחרון מצביעים על NIL. HEAD
אפשרות ב’: סגירה מעגלית (הצבעה על HEAD ) HEAD

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

15 מבני רשימות מיוחדים מחסנית STACK ניתן לגשת רק לראש. LIFO
דוגמה: מחסנית רובה ניירות על השולחן 1. MAKE NULL (S) 2. TOP (S) 3. POP (S) 4. PUSH (S) 5. EMPTY (S) (TRUE | FALSE) פעולות:

16 מימושים: ייעול: כל הרשימות בהגבלת טיפול רק בהתחלה.
רשימות מקושרות או סמנים: בסדר. מערך - בסדר. אבל בעיות יעילות ( כל הכנסה והוצאה (O(N ) : 1st 2nd : Last Element 1 2 3 MAXLENGTH TOP ייעול: Type STACK = record top: integer elements: array [1…MAXL] of element type] end ; שימושים: ברקורסיות ישום פעולות: פשוט. לבצע לבד.

17 תור Queue תור Queue פעולות: סוג מיוחד של רשימה FIFO
נכנסים ב- REAR , יוצאים ב- FRONT . F R פעולות: 1) MAKENULL (Q) 2) ENDQUEUE (x,Q) : INSERT (x,END (Q),Q) 3) FRONT (Q) : RET (FIRST (Q), Q) 4) DEQUEUE (Q) : DELETE (FIRST (Q), Q) 5) EMPTY (Q) : TRUE | FALSE

18 יישום כל היישומים הקודמים עובדים (רשימות) ליתר יעילות: יישום מיוחד. + צריכים לגשת לסוף + יישום ברשימה מקושרת חד כיוונית. איבר אחד ריק (נוחיות טיפול ברשימה ריקה) מצביעים על התחלה וסוף. TYPE QUEUE : Record front, rear :  celltype

19 דוגמאות לפעולות: MAKENULL (Q) ENQUEUE (X) ENQUEUE (Y) DEQUEUE (Q) Q
F R F= R EMPTY ENQUEUE (X) F R X ENQUEUE (Y) F R X Y DEQUEUE (Q) F R Y

20 יישום תור במערך (מעגלי)
1 2 N N 1 2 QUEUE Q.REAR Q.FRONT REAR, FRONT - נעים עם השעון FRONT - על ראשון, REAR - על אחרון F = R  איבר בודד F = R + 1  ריק F = R + 2  מלא שימו לב: ניתן להכניס רק N-1 איברים!!!!!! עבור כל F יש רק N אפשרויות ל- R ולכן ניתן לייצג רק: 0,1,2,……., N-1

21 שימוש מחסנית לביצוע רקורסיות
בצוע קריאה לסברוטינה רגילה:  גורם במחשב לשימור המשתנים וכתובת חזרה, ואז קפיצה לשגרה. בצוע חזרה מסברוטינה רגילה:  קריאת המשתנים ועדכונם וחזרה לכתובת החזרה Prog A . i = 15 Call B Subroutine B . i =9 return

22 סברוטינות רקורסיביות עקרון דומה - אך הקפיצה היא לאותה שגרה.
עקרון דומה - אך הקפיצה היא לאותה שגרה. - יכול לקפוץ הרבה פעמים (“לא חסום”) פתרון: שמור המשתנים וכתובת החזרה בתוך STACK. בכל קריאה לרקורסיה: הכנסת משתנים וכתובת -(PUSH(S חזרה למחסנית בכל חזרה מרקורסיה: הוצאת משתנים והכתובת (POP(S מהמחסנית ועדכון. בצוע חזרה לפי כתובת החזרה.

23 יישום רקורסיה בשפה שאין בה רקורסיה
נבצע אותו הדבר, אבל בעצמנו. נחזיק STACK שבו: 1) כל המשתנים הלוקאלים. 2) כתובת חזרה. 3) פרמטרי הקריאה. ערכם מוחזרים (לא הכרחי) Function FACT(N) If N <= 1 then return (1) ELSE begin M:= FACT(N-1) Return(N*M) (5) END

24 יישום לולאה באמצעות רקורסיה
finished 1/11/04 While X do  SUBROUTINE WHILE ( ) IF X then do begin CALL WHILE ( ) ELSE RETURN END תשומת לב: כל המשתנים שמשתנים במשך הלולאה וערכם הקודם משומש בלולאה הבאה צריכים להגיע כפרמטרים או כגלובאלים.

25 טבלאות דינאמיות מתאים ל- STACK, QUEUE ביישום מערך.
(cormen 18.4 , p.367) מתאים ל- STACK, QUEUE ביישום מערך. יתאים גם ל HASH, HEAP מטפל בבעיית חוסר המקום, שנוצר דינאמית במבנה מבוסס מערך. דוגמה: מחסנית מבוססת מערך - מה עושים כשמתמלאת? פתרון: (אלגוריתם): (שיטת ההכפלה Doubling) 1) הקצה מקום מסויים לטבלה (פשוט: N=2i) 2) כשהמקום מתמלא והטבלה מכילה N אלמנטים: א) הקצה מקום חדש לטבלה בגודל 2N ב) העתק איברים לטבלה החדשה. ג) שחרר טבלה ישנה.

26 סיבוכיות 1) עבור פעולת ׂPER OPERATION) : INSERT) אם אין הכפלה (O(1
2) AMORTIZED ANALYSIS CORMEN ) AMORTIZED COST) חשוב זמן ממוצע עבור פעולה במקרה הגרוע ביותר. שווה ל: T(n)/n , כאשר (T(n הוא סכום הפעולות על n פעולות. שיטת ההתחשבנות (ACCOUNTING) מחשבנים לפעולה עלות מסויימת. עשויה להיות גבוהה או נמוכה ממה שעולה. כשהעלות המחושבת גבוהה מהעלות בפועל שומרים Creditלעצמים (איברים) אחרים.

27 3) Amortized Complexity של שיטת ה- :Doubling
א) חישוב ישיר: עלות כוללת של n איברים : n הכנסות. … + n = 2n-1 העברות :  (T(n)=O(n יותר מדויק 1- T(n)=3n עלות מהוונת (Amortized) T(n)/n = 3

28 חישוב בשיטה החשבונאית (accounting)
הכנסת איבר n/2 בעת הכנסת איבר מחשבים לו עלות 3 1 - עבור הכנסתו. 1 - עבור העברתו בהעברה הבאה. 1 - כ”תרומה לחבר” (אחד מה- n/2 ) עבור העברתו בהעברה הבאה.

29

30 עצים (Trees) עצים Trees עץ = מבנה היררכי הגדרה רקורסיבית:
1. צומת בודד. זהו גם שורש העץ. 2. אם n הוא צומת ו T1….TK הינם עצים, ניתן לבנות עץ חדש שבו n השורש ו T1….TK הינם “תתי עצים”. T1 TK n . . . מושגים: צומת = Node עץ = Tree שורש = Root תת-עץ = Subtree

31 דוגמה: פרקים וסעיפים בספר
book c1 s1.1 s1.2 s1.3 c2 s2.1 s2.2 c3 s3.1 book c1 c2 c3 s1.1 s1.2 s1.3 s2.1 s2.2 s3.1 מושגים: book - הורה/Parent (אבא) של c1, c2, c3 c1, c2 - ילדים/children של book s2.1 - צאצא/Descendant (לא ישיר) של book n1, n2,…nk - מסלול/Path (אם כ”א הורה של הקודם) אורך המסלול = מס’ הקשתות = מס’ הצמתים (פחות אחד) צומת ללא ילדים = עלה/Leaf n1 - אב קדמון/Ancestor של nk

32 תת-עץ - צומת עם כל צאצאיו
גובה העץ - אורך המסלול הארוך ביותר מהשורש לעלה (height) עומק צומת - אורך המסלול מהצומת לשורש (depth) סדר בצמתים בד”כ - משמעות לסדר הילדים. מסדרים משמאל לימין. a b C אם הסדר לא חשוב - עץ לא מסודר (unordered tree)

33 צורות סיסטמטיות לסריקת הצמתים בעץ
צורות ססטמיות לסריקת הצמתים בעץ Preorder , postorder , Inorder הגדרה רקורסיבית: אם T הוא ריק - אזי הרשימה הריקה היא Preorder (Post,IN) אם T הוא צומת בודד (n) אזי הרשימה הבנויה מ- n הינה Post,In) Preorder) אחרת אם T הוא עץ עם שורש n ותתי עצים T1,…,Tk אזי : n, PRE(T1), … , PRE(TK) : PREORDER POST (T1), … , POST (TK), n : POST IN(T1), n , IN(T2), … ,IN(TK) : IN

34 Procedure PREORDER (n: node) (1) list n ;
(2) for each child c of n, in order from left do: PREORDER (C) end ; להשלים כתיבת POSORDER, INORDER בבית. 1 2 3 4 5 6 7 8 דוגמה: 1,2,3,4,5,6,7,8 : PRE 3,2,5,4,6,1,7,8 : IN 3,5,6,4,2,7,8,1 : POST

35 שיטה למספור הקף העץ בכיוון הפוך לשעון: PRE: סמן צומת בפעם הראשונה.
1 2 3 4 5 6 8 PRE: סמן צומת בפעם הראשונה. IN : סמן עלה בפעם הראשונה. סמן צומת פנימי בפעם השניה. POST: סמן צומת בפעם האחרונה.

36 עצים מסומנים ועצי ביטויים
(Labeled Trees, Expression Trees) עצים מסומנים: מסמנים את הצומת בסימון כלשהוא. עצי ביטויים: העץ מייצג ביטוי מתמטי. n1 n2 n3 n4 n5 n6 n7 * + a b c d דוגמה: = (a+b)*(c+d) חוקיות הביטוי בעץ ביטויים: 1. כל עלה מסומן באופרנד. 2. צומת פנימי מסומן בפעולה (אופרטור) ואם האופרטור בינארי ו- E1,E2 הינם ערכי הביטויים המבוטאים ע”י תתי העץ אזי הביטוי הוא: E E2 3. אופרטור אונרי - ילד יחידי.

37 סדר הסריקה של עצי ביטוי קובע יצוג שונה של הביטוי -
1. Inorder - היצוג הרגיל (a+b)*(c+d) 2. Postorder ( פולני) ab + cd +  (מחשבוני HP) (אין כפל משמעות !!) שימוש במספור לאינפורמציה שושלת אם POST : X 112 50 צמתים y Y= desc(x) 63-112 Post(x) - #desc(x) <= Post(y) <= Post(x)

38 מבנה נתונים אבסטרקטי של עץ
פעולות שיעניינו אותנו: 1. PARENT (N, T) - החזר את אבא של n ב T. אם n הוא השורש החזר Nil. 2. LEFTMOST_CHILD(n, T) - החזר הבן השמאלי ביותר של n בעץ T. Nil אם n עלה. RIGHT_SIBLING(n, T) 3. אח ימני של n ב Nil. T אם אין. 4. LABEL(n, T) - סימון n ב T. (לא נדרש תמיד). 5. (CREATi(r, T1,…Ti - יוצר עץ חדש עם שורש r שבו: א) r השורש מסומן ב U ב) ל r יש i בנים, i תתי עצים. T1,…Ti מחזיר עץ עם שורש r. r i=0 גם שורש וגם עלה.

39 6. ROOT(T) - החזרת השורש או Nil אם ריק.
7. MAKENULL(T) - יוצר את העץ הריק T. דוגמה: כתיבת PREORDER בעזרת ה ADT Procedure PREORDER (n: node) {list the descendants of n in PREORDER} var c: node; Begin print (LABEL (n, T)) c := LEFTMOST_CHILD(n, T); while c <> Nil do begin PREORDER(c); c := RIGHT_SIBLING(c, T) end; end; {PREORDER}

40 כתיבה לא רקורסיבית של PREORDER
נלך במורד העץ שמאלה ככל שנוכל כשלא ניתן נעבור לאח הימני של הצומת האחרון אם אין - נעלה למעלה ונזוז לאחיו הימני 1 2 3 4 5 6 8 7 9 בצוע וישום: נחזיק מחסנית ובה נאחסן בכל רגע את המסלול מהשורש עד לצומת שבו אנו מבקרים. מחסנית  רקורסיה

41 Procedure NPREORDER(T: TREE);
{nonrecursive preorder traversal of tree T} var m:node; {a temporary} S:STACK; {stack of nodes holding path from the root to the parent TOP(S) of the current node m} begin {initialize} MAKENULL(S); m:= ROOT(T); while true do if m < > L then begin print (LABEL(m, T)); PUSH(m, S); {explore leftmost child of m} m:= LEFTMOST_CHILD(m, T); end else begin {exploration of path on stack is now complete} if EMPTY(S) then return; {explore right sibling of node on top of stack} m:= RIGHT_SIBLING(TOP(S), T); POP(S); end; {NPREORDER}

42 ממוש עצים דוגמה: יצוג עץ באמצעות מערך (מערך הורים) :
X ממוש עצים יצוג עץ באמצעות מערך (מערך הורים) : יצוג פשטני התומך ב- PARENT מערך [A[i שבו [A[i הוא סמן (Cursor) להורה של i : בעיה לתמוך ב- LEFTMOST_CHILD RIGHT_SIBLING ניתן לייצג LABEL (במערך נוסף) 1 2 3 4 5 a b e d c דוגמה: T: a b c d e LABEL בעיית LCHILD ו- RSIBLING: לא מוגדר סדר מספיק בייצוג הנוכחי ! נניח: נשכן בנים אחרי האב ומשמאל לימין .

43 אזי - ישום R_SIBLING Function R_SIBLING (n:node ; T:Tree) node ;
X Function R_SIBLING (n:node ; T:Tree) node ; {return R_SIB of n in T (o else) } var i,parent: node ; begin parent:= T(n) for i:= n+1 to max nodes do if T(i) = parent then return (i) ; return (0) ; end ; DATA TYPES type node = integer TREE = array [ 1 … max nodes ] of node ; אזי - ישום R_SIBLING

44 ייצוג עצים על-ידי רשימות בנים
- לכל צומת - רשימת בניו - כל מבנה רשימה - קביל, אבל מספר בנים משתנה  עדיפות לרשימה מקושרת. דוגמה: 1 2 3 9 10 4 5 6 8 7 1 2 3 4 5 6 7 8 9 10 HEADER

45 מבנה הנתונים המופשט Type node = integer list = position =
Tree = record header: array[1..MAXNODES] of list labels: array[1..MAXNODES] of label type end; בצוע L-CHILD: Function L-CHILD(n: node, T: Tree): node; var L:list; begin L: T.header[n] if empty[L] then return(0); else return(RETRIEVE(FIRST(L), L)) end;

46 יישום ספציפי של הרשימה באמצעות מערך הסמנים
4 2 1 3 5 6 7 8 9 אח Header (בן שמאלי) node next cell space (רשימת אח ימני) יתרונות וחסרונות: ניתן למצוא ילד ואח במהירות. קשה למצוא הורים. קשה לחבר עצים (...,CREATEi(V אמנם כל התאים ב cellspace משותפים אבל לכל עץ header משלו.

47 פתרון פשוט פתרונות: כל האינפורמציה שהיתה היא: בן ראשון (שמאלי)
אח ראשון (ימני) 1 2 3 4 5 6 7 8 9 10 11 D B A C Left child label Right sibling הכל פשוט פרט ל Parent פתרונות: 1) הוסף שדה רביעי (עלות מקום, יעילות זמן) 2) אח ימני של האח הימני ביותר

48 איך מבצעים (CREATE2(V,T1,T2?
(בד”כ נשמור רשימת available לתאים פנויים) 2) V.left = T1 3) T1.right = T2

49 יישום עצים שרירותיים כל צומת מכיל 3 מצביעים: - בן שמאלי - אח ימני
- הורה (אופציונלי) a b d c g f e ניתן לממש באמצעות מצביעים או באמצעות Cursors

50 יישום ברשימת מצביעים (זהה!)
X A B C D lchild label rsibling A C D B שידוך עצים ברשימת מצביעים T1 ? temp 1 1) temp:= avail 3 3) cellspace[temp].LC:=T1 6 6) cellspace[T1]:=T2 2 2) avail:=cellspace[avail].R T2 ? v 4 4) cellspace[temp].label:=v Avail 5 5) cellspace[temp].RS:=0

51 עצים בינאריים - עץ ריק או לכל צומת יש תת קבוצה של {ילד ימני, ילד שמאלי} 1 2 3 4 5 6 7 דוגמא: הנ”ל: - זהים בעצים מסודרים - שונים בעצים בינאריים סדרי סקירה: Pre, Post - יתנו תוצאה זהה למה שיתנו בעץ סדור. In - לא בהכרח זהה!

52 ייצוג: 1) מערך של רשומות Var cellspace: array[1…maxnodes] of record
leftchild: integer rightchild: integer end; דוגמא: קוד Huffman - נתון סט של אותיות a, b, c, d, e - מופיעות בשפה בהסתברויות שונות: 0.12, 0.4, 0.15, 0.08, 0.25 - רוצים לקודד ל 0/1 בצורה יעילה אפשרות א’ - שלשות: a b c d e אפשרות ב’ - ייצוג קצר לאותיות שכיחות ייצוג ארוך לאותיות נדירות שימוש בקוד פרפיקסי = אף אות אינה פרפיקס של אחרת אורך ממוצע: 3

53 דוגמא: בעיה: בהינתן אותיות והסתברויות מצא קוד פרפיקסי יעיל.
a b c d e אורך ממוצע: 3( )+2( )=2.27 בעיה: בהינתן אותיות והסתברויות מצא קוד פרפיקסי יעיל. יצוג קוד פרפיקסי בעזרת עץ בינארי: 1 - אותיות בעלים - 0/1 בענפים (שמאל=0, ימין=1) - אותיות בעלים מבטיח פרפיקס ישום Huffman - יהיה לנו יער (אוסף עצים) - העלים = אותיות - מסלולים = סיומות של מילים - לכל עץ משקל = סכום ההסתברויות כל פעם שדך את העצים הקלים ביותר

54 דוגמא: a b c d e X1 0.2 X4 1.0 X2 0.35 X3 0.6 X4 X3 X2 X1 b 0.4 d 0.08 c 0.15 e 0.25 a 0.12 חישוב אורך ממוצע: a *4 d *4 c *3 e *2 b 0.4*1 2.15

55 מבנה נתונים 1) לשמור את מבנה העצים: לכל צומת אבא ובנים. 1 2 3 4 5 6 7
Lchild Rchild Parent Weight Root Forest 2) לכל עץ משקלו ושורשו.

56 3) שמירת האלף-בית (סטאטי)
a b c d e ALPHABET דינמיות - בכל פעולה מוסיפים צומת - מורידים עץ. - הוספת צומת - בסוף של TREE - הורדת עץ: מ T1 ו T2 יוצרים T. נבצע T T2+T1 - זריקת T2: החלף מקומות בין T2 ו TLAST והקטן האינדקס ל LAST

57 עצים בינאריים אחסון עצים בינאריים במערך: ניתן לישם באמצעות פוינטרים:
type node = record lchild : node rchild : node parent: node end אחסון עצים בינאריים במערך: טוב למבנה סטאטי אם צומת x בתא i : Ichild(x): 2i : אז Rchild(x): 2i+1 טוב במיוחד אם העץ מושלם (או שתילת עצים אחרים בחורים).

58 איך מבצעים (CREATEz (v,T1,Tz:
X איך מבצעים (CREATEz (v,T1,Tz: 1) צור רשימה חדשה V ותן לה סימון מתאים (בד”כ נשמור רשימת Avail לתאים פנויים) 2) V. left = T1 3) T1.right = T2


Download ppt "מבני נתונים מופשטים בסיסיים"

Similar presentations


Ads by Google