ΠΛΗ111 οµηµένος Προγραµµατισµός Ανοιξη 2005 Μάθηµα 4 ο Στοίβα Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης
Ανασκόπηση Αφηρηµένος Τύπος εδοµένων Στοίβα Υλοποίηση µε Πίνακα Υλοποίηση µε Συνδεδεµένη Λίστα Εφαρµογές Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 2
Αφηρηµένος Τύπος εδοµένων Στοίβα Συλλογή στοιχείων σε γραµµική διάταξη Επιτρέπει εισαγωγή και διαγραφή στο ένα µόνο άκρο της διάταξης, το οποίο ονοµάζουµε κορυφή LIFO (Last In First Out) Παραδείγµατα: στοίβα πιάτων, κερµατοθήκη Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 3
Βασικές Πράξεις Στοίβας create() : δηµιουργεί κενή στοίβα empty() : ελέγχει αν η στοίβα είναι κενή top() : επιστρέφει το στοιχείο της κορυφής push() : εισάγει στοιχείο στην κορυφή pop() : αφαιρεί/επιστρέφει το κορυφαίο στοιχείο κορυφή C B A Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 4
Υλοποίηση Στοίβας µε Πίνακα #define N /* µέγεθος πίνακα */ typedef struct { int stack[n]; int top; /* κορυφή στοίβας */ } stack_t, *stackptr_t; stack_t stack; void create(stackptr_t stackptr) { stackptr->top = -1; /* αρχικά άδεια */ } stack[n-1] stack[4] stack[3] stack[2] stack[1] stack[0] top #define empty(stack) ((stack).top == -1) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 5
Push µε Πίνακα σε Χρόνο Ο(1) stack[n-1] /* όρισµα δείκτη σε stack για αλλαγή στοιχείου */ void push(stackptr_t stackptr, int x) { if (stackptr->top == N-1) printf( stack full\n ); else stackptr->stack[++(stackptr->top)] = x; } stack[4] stack[3] stack[2] stack[1] stack[0] top Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 6
Pop µε Πίνακα σε Χρόνο Ο(1) stack[n-1] /* όρισµα δείκτη σε stack για αλλαγή κορυφής */ int pop(stackptr_t stackptr) { if (stackptr->top == -1) printf( empty stack\n ); else return stackptr->stack[(stackptr->top)--]; } stack[4] stack[3] stack[2] stack[1] stack[0] top Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 7
Υλοποίηση Στοίβας µε Λίστα typedef struct item { int data; struct item *next; } item_t, *itemptr_t; itemptr_t top; void create(itemptr_t *topptr) { } *topptr = NULL; top topptr #define empty(top) (top == NULL) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 8
Push µε Συνδεδεµένη Λίστα void push(itemptr_t *topptr, int x) { itemptr *newitem = (itemptr_t) malloc(sizeof(item_t)); topptr top newitem x } newitem->data = x; newitem->next = *topptr; *topptr = newitem; Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 9
Pop µε Συνδεδεµένη Λίστα int pop(itemptr_t *topptr) { } if (*topptr == NULL) printf( empty stack ); else { itemptr_t olditem = *topptr; int x = olditem->data; *topptr = (*topptr)->next; free(olditem); return x; } topptr top olditem x Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 10
Αριθµητικές Εκφράσεις Ενδοθεµατική αριθµητική (infix) Οι τελεστές (+,-,*,/) τοποθετούνται µεταξύ των όρων Σειρά εκτέλεσης από αριστερά προς τα δεξιά Προτεραιότητα πράξεων 1. Παρενθέσεις 2. Πολλαπλασιασµός/ ιαίρεση 3. Πρόσθεση/Αφαίρεση Παράδειγµα: (32 (7 + 5)) * (22 + 3 * 4) * - + 32 + 22 * 7 5 3 4 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 11
Εναλλακτικές Αριθµητικές Εκφράσεις Μεταθεµατική αριθµητική (postfix) Οι τελεστές (+,-,*,/) τοποθετούνται µετά τους όρους ε χρειάζεται προτεραιότητα ή παρενθέσεις Παράδειγµα: 32 7 5 + - 22 3 4 * + * ισοδυναµεί µε: ((32 (7 5 +) -) (22 (3 4 *) +) *) Προθεµατική αριθµητική (prefix) Οι τελεστές (+,-,*,/) τοποθετούνται πριν τους όρους ε χρειάζεται προτεραιότητα ή παρενθέσεις Παράδειγµα: * - 32 + 7 5 + 22 * 3 4 ισοδυναµεί µε: (* (- 32 (+ 7 5)) (+ 22 (* 3 4))) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 12
Παράδειγµα Μετατροπή Infix σε Postfix 7 5 * 3 + 4 => 7 5 3 * - 4 + Ιδέες ιαβάζουµε την infix έκφραση από αριστερά προς τα δεξιά Αν το επόµενο σύµβολο ακέραιος µεταφέρεται στην έξοδο Πρέπει όµως να τυπώσουµε και τους τελεστές στη σωστή σειρά τηρώντας την προτεραιότητά τους Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 13
Παράδειγµα Μετατροπής Infix σε Postfix 7 5 * 3 + 4 => 7 5 3 * - 4 + Σύµβολο Στοίβα Τελεστών Έξοδος 7 άδεια 7 - - 7 5-7 5 * * - 7 5 3 * - 7 5 3 + + 7 5 3 * - 4 + 7 5 3 * - 4 7 5 3 * - 4 + Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 14
Αλγόριθµος Μετατροπής Infix σε Postfix while not end of expression read token if token is operand output token if token is operator if (empty(stack)) push(token) else /* σύµβολα χαµηλής προτεραιότητας */ while ( not empty(stack) and (precedence of token <= precedence of top(stack)) ) output pop(stack) push(token) while (not empty(stack)) output pop(stack) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 15
ιαχείριση Παρενθέσεων Παράδειγµα (6 * (7 3 * 2) 7) * 2 => 6 7 3 2 * - * 7 2 * Ιδέες Σηµειώνουµε την αρχή µιας υποέκφρασης εισάγοντας ( στη στοίβα Συνεχίζουµε κανονικά τον υπολογισµό µέχρι να βρούµε ) Όταν βρούµε ) στην έκφραση εξάγουµε τους τελεστές της στοίβας µέχρι το πιο πρόσφατο ( Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 16
ιαχείριση Παρενθέσεων (6 * (7 3 * 2) 7) * 2 => 6 7 3 2 * - * 7 2 * Έκφραση Στοίβα Έξοδος ( ( 6 ( 6 * * ( 6 ( ( * ( 6 7 ( * ( 6 7 - - ( * ( 6 7 3 - ( * ( 6 7 3 * * - ( * ( 6 7 3 2 * - ( * ( 6 7 3 2 ) * ( 6 7 3 2 * - - - ( 6 7 3 2 * - * 7 - ( 6 7 3 2 * - * 7 ) άδεια 6 7 3 2 * - * 7 - * * 6 7 3 2 * - * 7-2 * 6 7 3 2 * - * 7-2 άδεια 6 7 3 2 * - * 7-2 * Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 17
Αλγόριθµος Μετατροπής µε Παρενθέσεις while not end of expression read token if token is operand output token if token is ( /* αρχή υποέκφρασης */ push(token, stack) if token is ) /* τέλος υποέκφρασης */ while (top(stack) <> ( ) output pop(stack) pop(stack) /* pop token ( */ if token is operator while (not empty(stack) and precedence of token <= precedence of top(stack) and top(stack) <> ( ) /* σύµβολα χαµηλής προτεραιότητας */ output pop(stack) push(token) while (not empty(stack)) /* εναποµείνοντα σύµβολα */ output pop(stack) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 18
Υπολογισµός Μεταθεµατικής Έκφρασης Ιδέες Γενικά κάνουµε υπολογισµούς όταν βρίσκουµε δύο ακεραίους που ακολουθούνται από τελεστή Eισάγουµε κάθε ακέραιο που βρίσκουµε σε στοίβα Κάθε φορά που συναντούµε τελεστή Εξάγουµε τους τελευταίους δύο ακεραίους από τη στοίβα Εκτελούµε την πράξη του τελεστή Εισάγουµε το αποτέλεσµα της πράξης στη στοίβα Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 19
Παράδειγµα Υπολογισµού 6 7 3 2 * - * 7 2 * => -2 Στοίβα Εισόδου Στοίβα Όρων 6 7 3 2 * - * 7 2 * 7 3 2 * - * 7 2 * 6 3 2 * - * 7 2 * 7 6 2 * - * 7 2 * 3 7 6 * - * 7 2 * 2 3 7 6 - * 7 2 * 6 7 6 * 7 2 * 1 6 7-2 * 6-2 * 7 6 2 * -1 * 2-1 άδεια -2 Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 20
Αλγόριθµος Μεταθεµατικού Υπολογισµού while (not empty(stack)) /* στοίβα εισόδου */ arithtoken = pop(stack) if (arithtoken is operand) push(arithtoken, temp) /* στοίβα ορισµάτων */ else operand2 = pop(temp) /* εκτέλεση πράξης */ operand1 = pop(temp) result = apply arithtoken to operands 1 & 2 push(result, temp) Ανοιξη 2005 Στέργιος Β. Αναστασιάδης 21