ADT Abstract Data Types

24
1 ADT Abstract Data Types The Stack Example

description

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

Transcript of ADT Abstract Data Types

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 הראשון (לא הגנרי) ולא מוסיפים תובנה עמוקה - בסך הכל שיטה אחרת להעברת פרמטרים.