Upload
arvid
View
25
Download
0
Embed Size (px)
DESCRIPTION
ADT Abstract Data Types. The Stack Example. ADT. לצורך הכרות עם מבנה נתונים הממומש כ ADT ניעזר בדוגמה הבאה לאורך השיעור:. יוצגו שלושה פתרונות לבעיה זו : פתרון ישיר ופשוט - נועד להמחשת הבעיה. - PowerPoint PPT Presentation
Citation preview
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 .)
: הבאות בפעולות תומך הטיפוס
• pushpush . ) למחסנית - ) תו איבר הוסף
• poppop ) שהוכנס - ) האחרון התו האיבר את הוצא.) ערכו ) את להחזיר מבלי למחסנית
• toptop ) האחרון - ) התו האיבר של ערכו את החזראותו ) להוציא מבלי למחסנית שהוכנס
מהמחסנית(.
• countcount . ) במחסנית - ) יש תווים איברים כמה
ובנוסף:
• createcreate.) ריק - ) מחסנית מסוג נתונים מבנה צור
• 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
מימוש אפשרי של המחסניתנגדיר מבנה שבו שלושה
שדות:
מערך בו ישמרו התווים.•
שדה אשר ישמור את גודל •המערך )וכתוצאה את מספר התווים המקסימלי שיכולים
להישמר(
שדה שישמור את מספר •התווים השמורים במחסנית - שהנו גם האינדקס במערך
אליו יוכנס התו הבא.
‘a’
top
‘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 ;int top ;int maxCapacity ;
} ;
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
שימוש בטיפוס הנתונים האבסטרקטי#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;
}
חסר ? מה
התחשבות 200היפוך תוך תוויםהאי ) כל יופיעו קודם בזוגיותכך ואחר הפוך בסדר זוגיים
) הפוך בסדר הזוגיים
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 ;int top ;int maxCapacity ; cpy_func cp_elm; free_func fr_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היפוך
#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בתוכן
? שנראה כדי מחרוזות למהשהוא טיפוס עם שהעבודה
במיוחד קשה איננה מורכב יחסיתשל הפרטי למקרה .charביחס
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 ; }
25