1 / 24

ADT Abstract Data Types

ADT Abstract Data Types. The Stack Example. ADT. לצורך הכרות עם מבנה נתונים הממומש כ ADT ניעזר בדוגמה הבאה לאורך השיעור:. יוצגו שלושה פתרונות לבעיה זו : פתרון ישיר ופשוט - נועד להמחשת הבעיה.

tibor
Download Presentation

ADT Abstract Data Types

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ADTAbstract Data Types The Stack Example

  2. ADT לצורך הכרות עם מבנה נתונים הממומש כ ADT ניעזר בדוגמה הבאה לאורך השיעור: יוצגו שלושה פתרונות לבעיה זו : • פתרון ישיר ופשוט - נועד להמחשת הבעיה. • פתרון אשר נעזר ב ADT של מחסנית - פתרון זה מפריד בין האפליקציה לבין מבנה הנתונים ומאפשר להיעזר במחסנית גם בתוכניות אחרות אולם מייצר מבנה נתונים המאפשר לשמור רק תווים. • פתרון אשר נעזר ב ADT גנרי - כלומר ADT המאפשר להגדיר מחסניות השומרות טיפוסי נתונים שונים – ובפרט תווים. נרצה לקרוא מהקלט הסטנדרטי 100 תווים ולהדפיסם בסדר הפוך לסדר בו נקראו.

  3. תוכנית להיפוך 100 תווים Reverese.c #include <stdio.h> int main() { int c ; char array[100]; int cur = 0; while ((c=getchar()) != EOF && cur<100) { array[cur] = c ; cur++ ; } while (cur) printf( "%c\n", array[--cur]) ; return 0; }

  4. הטיפוס האבסטרקטי - מחסנית • המחסנית (שנראה כעת) הנה טיפוס המאפשר שמירת מספר מסוים של תווים, כאשר בכל רגע נתון נגיש רק התו האחרון שהוכנס למחסנית (Last In First Out). • הטיפוס תומך בפעולות הבאות: • push - הוסף איבר (תו) למחסנית. • pop - הוצא את האיבר (התו) האחרון שהוכנס למחסנית (מבלי להחזיר את ערכו). • top - החזר את ערכו של האיבר (התו) האחרון שהוכנס למחסנית (מבלי להוציא אותו מהמחסנית). • count - כמה איברים (תווים) יש במחסנית. • ובנוסף: • create - צור מבנה נתונים מסוג מחסנית (ריק). • destroy - הרוס את מבנה הנתונים מחסנית. • http://www.cosc.canterbury.ac.nz/people/mukundan/dsal/StackAppl.html

  5. טיפוס נתונים אבסטרקטי - ממשק I Stack.h #ifndef _STACK_H #define _STACK_H /* ADT of Stack of characters */ typedef struct Stack_t* Stack ; /* possible return values */ typedef enum {Fail, Success} Result ; /* IMPORTANT all functions get the stack that they should work on ! */ /* creates a Stack. sets the stack maximal capcity to max_size. If fails, returns NULL*/ Stack create(int max_size) ; /* releases the memory allocated for the stack. */ void destroy(Stack s) ;

  6. טיפוס נתונים אבסטרקטי - ממשק II /* insert a char to the top of the stack. fails if s==NULL, or if the stack is full. */ Result push(Stack s, char c) ; /* removes the char at the top of the stack. fails if s == NULL, or if the stack is empty. */ Result pop(Stack s) ; /* returns in pc the last element that was pushed. Fails if s == NULL or pc == NULL or if the stack s is empty. */ Result top(Stack s, char* pc) ; /* returns the number of elements in the stack. Returns -1 if s == NULL. */ int count(Stack s); #endif

  7. מימוש אפשרי של המחסנית נגדיר מבנה שבו שלושה שדות: • מערך בו ישמרו התווים. • שדה אשר ישמור את גודל המערך (וכתוצאה את מספר התווים המקסימלי שיכולים להישמר) • שדה שישמור את מספר התווים השמורים במחסנית - שהנו גם האינדקס במערך אליו יוכנס התו הבא. top ‘a’ ‘z’ ‘b’ ‘a’

  8. טיפוס נתונים אבסטרקטי - מימוש I Stack.c #include <stdlib.h> #include "Stack.h" /* a structure that represents a Stack. one structure for each Stack */ struct Stack_t { /* The Stack is implemented as an array of characters. With top as an index to the next available position and maximal size stored in maxCapacity. */ char* array ; inttop ; intmaxCapacity ; } ;

  9. טיפוס נתונים אבסטרקטי - מימוש II Stack create(int max_size) { Stack s ; char* tmp = NULL; if (max_size <=0) return NULL ; s = (Stack) malloc (sizeof(struct Stack_t)) ; if (s == NULL) return NULL; tmp= (char*) malloc (max_size) ; if (tmp == NULL) { free (s) ; return NULL ; } s->top = 0; s->maxCapacity = max_size ; s->array = tmp; return s; }

  10. טיפוס נתונים אבסטרקטי - מימוש III Result push(Stack s, char c) { if ((s == NULL) || (s->top >= s->maxCapacity)) return Fail ; s->array[s->top] = c ; s->top++ ; return Success ; } Result pop(Stack s) { if ((s == NULL) || (s->top == 0)) return Fail ; s->top--; return Success ; }

  11. טיפוס נתונים אבסטרקטי - מימוש IV Result top(Stack s, char* pc) { if ((s == NULL) || (s->top == 0) || (pc == NULL)) return Fail ; *pc = s->array[s->top-1]; return Success ; } int count(Stack s) { if ((s == NULL)) return -1; return s->top ; } Result destroy(Stack s) { if (s == NULL) return; free(s->array); free(s); }

  12. היפוך 200 תווים תוך התחשבות בזוגיות (קודם יופיעו כל האי זוגיים בסדר הפוך ואחר כך הזוגיים בסדר הפוך) שימוש בטיפוס הנתונים האבסטרקטי #include <stdio.h> #include "Stack.h" int main() { int c ; char t ; Stack even, odd ; even=create(100) ; odd=create(100) ; while(1) { if ((c = getchar()) == EOF) break ; push(even,c); if ((c = getchar()) == EOF) break ; push(odd,c); } while (count(odd) > 0) { top(odd,&t ); putchar(t); pop(odd); } while (count(even) > 0) { top(even,&t ); putchar(t); pop(even); } return 0; } מה חסר ?

  13. Generic ADT The stack example generic version

  14. Generic ADT שימוש במצביעים לפונקציות ב ADT לרוב ל ADT לא משנה איזה טיפוסי נתונים יכיל, בין אם הם מחרוזות, מבנים, שלמים או תווים. בכל מקרה ה-“לוגיקה” של ה ADT תהיה זהה. למשל, מחסנית תמיד תוציא את האיברים שהוכנסו אליה בסדר הפוך לסדר ההכנסה (LIFO) - ללא קשר לטיפוס האיברים. על כן, נרצה לכתוב ADTכללי שמסוגל להכיל איברים מכל טיפוס שהוא. בדרך זו מספיק לכתוב את ה-ADT רק פעם אחת כדי שנקבל ADT שמסוגל לפעול על כל סוג של נתונים. הבעיה הנה שה-ADT לא ידע כיצד לבצע פעולות פשוטות הנוגעות לאיברים - למשל להעתיק איבר, להדפיס איבר, למחוק איבר וכדומה, שכן ביצוע פעולות אלו דורש ידיעה של סוג הטיפוס שנמצא ב-ADT. הפתרון לבעיה זו הוא שימוש במצביעים לפונקציות: המשתמש ב-ADT מעביר בעת אתחול ה-ADT מצביעים לפונקציות שמבצעות את הפעולות הספציפיות לטיפוס.

  15. טיפוס נתונים אבסטרקטי - ממשק I Stack.h #ifndef STACK_H #define STACK_H /* ADT of a generic Stack */ typedef struct Stack_t* Stack ; typedef void* Elem; typedef Elem (*cpy_func)(Elem); typedef void (*free_func)(Elem); /* possible return values */ typedef enum {Fail, Success} Result ; /* Initialize the Stack. Sets the stack maximal capacity to max_size. Save pointers to functions. If fails, return NULL */ Stack create(int max_size, cpy_func cpy_elm, free_func free_elm ); /* Releases all the resources of the stack */ void destroy (Stack s) ;

  16. טיפוס נתונים אבסטרקטי - ממשק II /* Insert a copy of the element to the top of the stack. Fails if s == NULL, or elm == NULL or if the stack is full. */ Result push(Stack s, Elem elm) ; /* Removes the elment at the top of the stack. Fails if s == NULL or if the stack is empty. */ Result pop(Stack s) ; /* Returns a copy of the element in the top of the stack. Fails if s == NULL or pelem == NULL. */ Result top(Stack s, Elem* pelm) ; /* Returns the number of elements in the stack. Returns -1 if s == NULL. */ int count(Stack s); #endif

  17. טיפוס נתונים אבסטרקטי - מימוש I Stack.c #include <stdlib.h> #include "Stack.h" /* A structure that represents a Stack. One structure for each Stack */ /* Each stack keeps pointers to functions that treat elements */ struct Stack_t { Elem* array ; inttop ; intmaxCapacity ; cpy_funccp_elm; free_funcfr_elm; } ;

  18. טיפוס נתונים אבסטרקטי - מימוש II Stack create(int max_size, cpy_func copy_elm, free_func free_elm){ Stack s ; if (max_size <=0 || free_elm==NULL || copy_elm == NULL) return NULL ; s = (Stack) malloc (sizeof(struct Stack_t)) ; if (s== NULL) return NULL; s->array = (Elem*)malloc(max_size*sizeof(Elem)) ; if (s->array == NULL) { free(s) ; return NULL ; } s->top = 0; s->maxCapacity = max_size ; s->cp_elm = copy_elm ; s->fr_elm = free_elm; return s ; }

  19. טיפוס נתונים אבסטרקטי -מימוש III Result push(Stack s, Elem elm) { Elem tmp = NULL; if ( s == NULL || elm == NULL || s->top >= s->maxCapacity ) return Fail; tmp = s->cp_elm(elm) ; if (tmp == NULL) return Fail ; s->array[s->top] = tmp; s->top++ ; return Success ; }

  20. טיפוס נתונים אבסטרקטי -מימוש IV Result pop(Stack s) { if ((s == NULL) || (s->top == 0)) return Fail ; s->top--; s->fr_elem(s->array[s->top]); return Success ; } Result top(Stack s, Elem* pelm) { Elem tmp = NULL; if (s == NULL || s->top == 0 || pelm == NULL) return Fail ; tmp = s->cp_elm(s->array[s->top -1]); *pelm = tmp; return (tmp == NULL) ? Fail : Success ; }

  21. טיפוס נתונים אבסטרקטי -מימוש V int count(Stack s) { if (s == NULL) return -1; return s->top; } void destroy (Stack s) { if (s == NULL) return; while (s->top> 0 && pop(s) == Success) ; free(s->array); free(s); } האם התנאי דרוש?

  22. שימוש בטיפוס הנתונים האבסטרקטי:היפוך 100 מחרוזות למה מחרוזות? כדי שנראה שהעבודה עם טיפוס שהוא יחסית מורכב איננה קשה במיוחד ביחס למקרה הפרטי של char. #include <stdio.h> #include <string.h> #include "Stack.h" /* functions that will be used by the ADT */ Elem cp_str(Elem s) { char *cp; if (s == NULL) return NULL; cp = (char*) malloc (strlen((char*) s) + 1); strcpy(cp, (char*) s); return cp; } void fr_str (void* s) { free (s); } בכדי שנוכל לנצל ב ADT את המצביעים לפונקציות על כולן להיות עם אותו ממשק, לכן במקום לציין את הטיפוס בו הן מטפלות כחלק מהגדרת הפונקציה, נגדירן תמיד כפונקציות המטפלות ב *void ונבצע בתוכן casting.

  23. המשך דוגמא int main() { char str[256] ; Elem tmp; Stack st ; st = create (100, cp_str, fr_str) ; if (st == NULL) return 1 ; while(fgets(str,256,stdin) != NULL) push(st,(Elem) str); while (count(st) > 0) { top(st, &tmp) ; printf (“%s\n”, (char*) tmp); pop(st); fr_str(tmp); } destroy(st); return 0; }

  24. דרך נוספת לבצוע אתחול מבנהשימוש במצביע למצביע Result create(Stack* ps, int max_size) { Stack s = NULL ; if ((max_size <=0) || (ps == NULL)) return Fail ; *ps = NULL; s = (Stack) malloc (sizeof(struct Stack_t)) ; if (s == NULL) return Fail; s->array = (char*) malloc (max_size) ; if (s->array == NULL) { free (s) ; return Fail ; } s->top = 0; s->maxCapacity = max_size ; *ps = s ; /* VERY IMPORTANT */ return Success ; }

More Related