adt abstract data types

25
1 ADT Abstract Data Types The Stack Example

Upload: arvid

Post on 24-Jan-2016

25 views

Category:

Documents


0 download

DESCRIPTION

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

TRANSCRIPT

Page 1: ADT Abstract Data Types

1

ADTAbstract Data Types

The Stack Example

Page 2: ADT Abstract Data Types

2

ADT

יוצגו שלושה פתרונות לבעיה זו :

- נועד להמחשת הבעיה.פתרון ישיר ופשוט•- של מחסנית ADTפתרון אשר נעזר ב •

פתרון זה מפריד בין האפליקציה לבין מבנה הנתונים ומאפשר להיעזר במחסנית גם

בתוכניות אחרות אולם מייצר מבנה נתונים המאפשר לשמור רק תווים.

ADT- כלומר גנרי ADTפתרון אשר נעזר ב •המאפשר להגדיר מחסניות השומרות טיפוסי

נתונים שונים – ובפרט תווים.

לצורך הכרות עם מבנה נתונים הממומש ניעזר בדוגמה הבאה לאורך ADTכ

השיעור: 100נרצה לקרוא מהקלט הסטנדרטי

תווים ולהדפיסם בסדר הפוך לסדר בו .נקראו

Page 3: ADT Abstract Data Types

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;}

Page 4: ADT Abstract Data Types

4

הטיפוס האבסטרקטי - מחסנית ) המאפשר ) טיפוס הנה כעת שנראה המחסנית

, רגע בכל כאשר תווים של מסוים מספר שמירתלמחסנית ) שהוכנס האחרון התו רק נגיש Lastנתון

In First Out .)

: הבאות בפעולות תומך הטיפוס

• pushpush . ) למחסנית - ) תו איבר הוסף

• poppop ) שהוכנס - ) האחרון התו האיבר את הוצא.) ערכו ) את להחזיר מבלי למחסנית

• toptop ) האחרון - ) התו האיבר של ערכו את החזראותו ) להוציא מבלי למחסנית שהוכנס

מהמחסנית(.

• countcount . ) במחסנית - ) יש תווים איברים כמה

ובנוסף:

• createcreate.) ריק - ) מחסנית מסוג נתונים מבנה צור

• destroy. מחסנית - הנתונים מבנה את הרוס

http://www.cosc.canterbury.ac.nz/people/mukundan/dsal/StackAppl.html

Page 5: ADT Abstract Data Types

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) ;

Page 6: ADT Abstract Data Types

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

Page 7: ADT Abstract Data Types

7

מימוש אפשרי של המחסניתנגדיר מבנה שבו שלושה

שדות:

מערך בו ישמרו התווים.•

שדה אשר ישמור את גודל •המערך )וכתוצאה את מספר התווים המקסימלי שיכולים

להישמר(

שדה שישמור את מספר •התווים השמורים במחסנית - שהנו גם האינדקס במערך

אליו יוכנס התו הבא.

‘a’

top

‘z’

‘b’

‘a’

Page 8: ADT Abstract Data Types

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 ;

} ;

Page 9: ADT Abstract Data Types

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;}

Page 10: ADT Abstract Data Types

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 ;

}

Page 11: ADT Abstract Data Types

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);

}

Page 12: ADT Abstract Data Types

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היפוך תוך תוויםהאי ) כל יופיעו קודם בזוגיותכך ואחר הפוך בסדר זוגיים

) הפוך בסדר הזוגיים

Page 13: ADT Abstract Data Types

13

Generic ADT

The stack example

generic version

Page 14: ADT Abstract Data Types

14

Generic ADTשימוש במצביעים לפונקציות ב

ADT

לא משנה איזה טיפוסי נתונים יכיל, ADTלרוב ל בין אם הם מחרוזות, מבנים, שלמים או תווים.

תהיה ADTבכל מקרה ה-“לוגיקה” של ה זהה.

למשל, מחסנית תמיד תוציא את האיברים שהוכנסו אליה בסדר הפוך לסדר ההכנסה

)LIFO.ללא קשר לטיפוס האיברים - ( שמסוגל להכיל כללי ADTעל כן, נרצה לכתוב

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

ADT.שמסוגל לפעול על כל סוג של נתונים לא ידע כיצד לבצע ADTהבעיה הנה שה-

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

. הפתרון ADTשל סוג הטיפוס שנמצא ב-לבעיה זו הוא שימוש במצביעים לפונקציות:

מעביר בעת אתחול ADTהמשתמש ב- מצביעים לפונקציות שמבצעות את ADTה-

הפעולות הספציפיות לטיפוס.

Page 15: ADT Abstract Data Types

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) ;

Page 16: ADT Abstract Data Types

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

Page 17: ADT Abstract Data Types

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;

} ;

Page 18: ADT Abstract Data Types

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 ; }

Page 19: ADT Abstract Data Types

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 ;

}

Page 20: ADT Abstract Data Types

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 ;}

Page 21: ADT Abstract Data Types

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);

}

? דרוש התנאי האם

user
שיניתי כאן את המימוש. קודם פשוט כתבו כאן את פופ מחדש...
Page 22: ADT Abstract Data Types

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ביחס

Page 23: ADT Abstract Data Types

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;

}

Page 24: ADT Abstract Data Types

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 ; }

user
השקף כולו נראה לי מיותר ומבלבל למדי. הם פתאום חוזרים ל-ADT הראשון (לא הגנרי) ולא מוסיפים תובנה עמוקה - בסך הכל שיטה אחרת להעברת פרמטרים.
Page 25: ADT Abstract Data Types

25