Ε. ΠετράκηςΣτοίβες, Ουρές1 Στοίβες Στοίβα: περιορισμένη ποικιλία λίστας τα στοιχεία μπορούν να εισαχθούν ή να διαγραφούν μόνο από μια άκρη : λίστες LIFO κορυφή: το προσβάσιμο άκρο της λίστας πράξεις: “push”, “pop” πολλές εφαρμογές εύκολο στην εφαρμογή: πίνακες διασυνδεδεμένες λίστες FEDCBAFEDCBA κορυφή
Ε. ΠετράκηςΣτοίβες, Ουρές2 Εφαρμογή σε Πίνακα Μια απλοποιημένη έκδοση εφαρμογής λίστας πίνακας σταθερού μεγέθους κορυφή: πάντα το πρώτο στοιχείο ο τρέχων είναι πάντα το στοιχείο της κορυφής push: εισαγωγή στην κορυφή ! pop: αφαίρεση από την κορυφή !
Ε. ΠετράκηςΣτοίβες, Ουρές3 template class Stack { private: int size; // Μέγιστο μέγεθος int top;// Στοιχείο Κορυφής ELEM * listarray; //ο πίνακας που κρατάει τα στοιχεία public: Stack (const int sz = LIST_SIZE)//κατασκευαστής {size = sz; top = 0; listarray = new ELEM[sz};} ~Stack( ) { delete [ ] listarray;} //καταστροφέας:επέστρεψε το κενό void clear( ) {top = 0;} //αφαίρεσε όλα τα στοιχεία void push(const ELEM& item) //push στοιχείο στη στοίβα {assert (top<size); listarray[top++] = item;} ELEM pop( ) // pop στοιχείο από την κορυφή {assert (!isEmpty( )); return listarray[--top];} ELEM topValue( ) const // τιμή του στοιχείου κορυφής {assert(!isEmpty( )); return listarray[top-1];} bool isEmpty( ) const// ΑΛΗΘΕΙΑ αν η στοίβα είναι άδεια {return top==0;} }; μέγεθος κορυφή μέγεθος
Ε. ΠετράκηςΣτοίβες, Ουρές4 Εφαρμογή Δυναμικής Μνήμης Απλοποιημένη έκδοση εφαρμογής διασυνδεδεμένης λίστας οι δείκτες κεφαλή και ουρά της εφαρμογής λίστας δεν χρησιμοποιούνται κεφαλή
Ε. ΠετράκηςΣτοίβες, Ουρές5 template class Stack { private: link *top;// δείκτης στην κορυφή του στοιχείου της στοίβας public: Stack (const int) // κατασκευαστής: αρχικοποίηση { top = NULL; } ~Stack( ) { clear( ); } // καταστροφέας: επέστρεψε τα στοιχεία void clear( ) { } // αφαίρεσε όλα τα στοιχεία void push (const ELEM& item)// push στοιχείο στη στοίβα {top = new link (item, top); } ELEM pop( ); ELEM topValue( ) const// τιμή του στοιχείου κορυφής {assert(!isEmpty( )); return top element;} bool isEmpty( ) const // ΑΛΗΘΕΙΑ αν είναι άδεια {return top == NULL; } };
Ε. ΠετράκηςΣτοίβες, Ουρές6 Εφαρμογές Έλεγχος μαθηματικών πράξεων Ίσος αριθμός από δεξιά/αριστερά (, {, [, ), }, ] λάθος
Ε. ΠετράκηςΣτοίβες, Ουρές7 Αλγόριθμός Διάβασε τις πράξεις από τα αριστερά προς τα δεξιά p: το επόμενο σύμβολο μέσα σε πράξη Repeat until (empty(stack) ) { read(p); if p = ( or { or [ then push(stack,p); loop; if p = ) or } or ] then c = pop(stack); if c != p then error!! } if (not empty(stack) ) then error!!
Ε. ΠετράκηςΣτοίβες, Ουρές8 [((([((( (
Ε. ΠετράκηςΣτοίβες, Ουρές9 Περισσότερες Εφαρμογές Εκτίμηση των αριθμητικών πράξεων: μετέτρεψε το infix σε postfix ή prefix εκτίμησε τη postfix ή τη prefix εφαρμογή infix, prefix, postfix: αναφέρετε στη σχετική θέση του τελεστή με βάση τους τελεσταίους infix : A+B prefix : +AB postfix : AB+
Ε. ΠετράκηςΣτοίβες, Ουρές10 Infix σε Postfix ή Prefix Διάβασε από τα αριστερά προς τα δεξιά Πρώτα μετέτρεψε τις πράξεις υψηλότερης αξίας οι παρενθέσεις έχουν την μεγαλύτερη αξία “^” έχει αξία μεγαλύτερη από “*”, “/” έχουν ίση αξία αλλά μεγαλύτερη από “+”, “-” τα οποία έχουν την ίδια αξία Το αλλαγμένο prefix ή postfix κομμάτι μεταχειρίζεται σαν ανεξάρτητος τελεσταίος Αν όλοι τελεστές έχουν την ίδια αξία τότε μετέτρεψε από τα αριστερά προς τα δεξιά
Ε. ΠετράκηςΣτοίβες, Ουρές11 Infix σε Postfix ή Prefix (συν.) A+B*C : ‘*’ > ‘+’ A+(B*C) : ισότιμο Α+(ΒC*) : B*C σε postfix ABC*+ : postfix (A+B)*C : (…) > ‘*’ (AB+)*C : A+B σε postfix (AB+)C* : (AB+)*C σε postfix AB+C* : postfix Τα Postfix και Prefix δεν έχουν παρενθέσεις!!
Ε. ΠετράκηςΣτοίβες, Ουρές12 Infix σε Postfix ή Prefix (συν.) A+B-C : ΑΒ+C- postfix (A+B)*(C-D) : AB+CD-* Α$Β*C-D+E/F/(G+H) : AB$C*D-EF/GH+/+ A-B/(C*D$E) : ABCDE$*/- A+B-C : -+ABC prefix (A+B)*(C-D) : *+AB-CD A$B*C-D+E/F/(G+H) : +-*$ABCD//EF+GH A-B/(C*D$E) : -A/B*C$DE
Ε. ΠετράκηςΣτοίβες, Ουρές13 Μετατροπή του infix σε postfix Διάβασε τις πράξεις από τα αριστερά προς τα δεξιά τελεσταίοι εξόδου σπρώξε τους τελεστές στη στοίβα υψηλότερης προτεραιότητας τελεστές πρέπει να είναι κάτω από τους χαμηλότερης προτεραιότητας πριν σπρώξεις τον τελεστή στην στοίβα έλεγξε την προτεραιότητα των προηγούμενων τελεστών αν ο τελεστής στην στοίβα έχει μεγαλύτερη προτεραιότητα βγάλε αυτόν τον τελεστή και μετά βάλε τον τρέχων τελεστή στην στοίβα “(”, “[”, “{” έχουν μεγαλύτερη προτεραιότητα, σπρώξε στη στοίβα αν “)”, “]”, “}” βγάλε από τη στοίβα μέχρι “(”, “[”, “{” να βρεθεί μην κάνεις εξαγωγή “(”, “[”, “{”, “)”, “]”, “}”
Ε. ΠετράκηςΣτοίβες, Ουρές14 Infix σε Postfix Παράδειγμα (A + B) * C βάλε “ ( ” στη στοίβα εξαγωγή του A βάλε “+” στη στοίβα εξαγωγή του B μη βάλεις “ ) ”, εξαγωγή σε όλους τους τελεστές εξαγωγή “+”, αγνόησε “ ( ”, “ ) ” “ * ” βάλε στη στοίβα εξαγωγή C εξαγωγή “+”
Ε. ΠετράκηςΣτοίβες, Ουρές15 Σύμβολο ( A + B ) * C Postfix A AB AB+ AB+C AB+C * Στοίβα ( (+ * Παράδειγμα: (A + B)*C
Ε. ΠετράκηςΣτοίβες, Ουρές16 Αλγόριθμος stack = NULL; while (not end of input) { symbol = read next symbol; if (symbol == operand) output(symbol); else { while(!empty(stack) && (preced (stack(top)) > preced(symbol)) { top symbol = pop(stack); output(top symbol); } push(stack, symbol); } while not_empty(stack) { top symbol = pop(stack); output(top symbol); }
Ε. ΠετράκηςΣτοίβες, Ουρές17 Εκτίμηση του Postfix While (not end of expression) { read symbols from left to right; result = 0 if (symbol == operand) push (stack); else { operand1 = pop(stack); operand2 = pop(stack); result = operand1 operator operand2; push(stack, result); } result = pop(stack);
Ε. ΠετράκηςΣτοίβες, Ουρές18 Postfix: / + * 2 $ 3 + Σύμβολο / + * 2 $ 3 + Τελεσταίος Τελεσταίος Τιμή Στοίβα τελεστών 6 6,2 6,2,3 6,5 1 1,3 1,3,8 1,3,8,2 1,3,4 1,7 7 7, ,3 52
Ε. ΠετράκηςΣτοίβες, Ουρές19 Ουρά Τα στοιχεία της ουράς μπορούν να εισαχθούν μόνο από πίσω και να εξαχθούν από μπροστά Περιορισμένη μορφή λίστας FIFO: first in first out εισαγωγή: enqueue πράξη εξαγωγή: dequeue πράξη
Ε. ΠετράκηςΣτοίβες, Ουρές20 A B C A B C D B C D μπροστά πίσω enqueue (queue, D) dequeue (queue)
Ε. ΠετράκηςΣτοίβες, Ουρές21 Εφαρμογή σε Πίνακα Αν τα στοιχεία είναι στα πρώτα n στοιχεία του πίνακα και το μπροστινό στοιχείο είναι στη θέση 0 Η enqueue χρειάζεται Θ(1) πράξεις αλλά, Η dequeue χρειάζεται Θ(n) πράξεις (όλα τα στοιχεία πρέπει να μετακινηθούν) Η κατάσταση της άδειας ουράς είναι επίσης ένα πρόβλημα
Ε. ΠετράκηςΣτοίβες, Ουρές22 μπροστά = 4 πίσω = 4 μπροστά = 4 πίσω = A Κατάσταση άδειας ουράς: πίσω = μπροστά Αρχικές τιμές: πίσω = μπροστά = LIST_SIZE - 1 το μπροστά δείχνει στη θέση που θα πάει το πρώτο στοιχείο
Ε. ΠετράκηςΣτοίβες, Ουρές23 D C B Α E D C B Α μπροστά = 4 πίσω = 2 μπροστά = 4 πίσω = 3 μπροστά = 4 πίσω = 4 Η κατάσταση της άδειας ουράς είναι αλήθεια αλλά η ουρά δεν είναι άδεια Το “E” δεν μπορεί να εισαχθεί: Η τελευταία θέση του πίνακα πρέπει να μείνει άδεια C B Α
Ε. ΠετράκηςΣτοίβες, Ουρές24 D C B Α Α Σβήσε το “Α” μπροστά = 0 πίσω = 3 D C B B Σβήσε το “B” μπροστά = 1 πίσω = 3 E D C F Βάλε τα “E”, “F” Κυκλική Λίστα μπροστά = 2 πίσω = 0
Ε. ΠετράκηςΣτοίβες, Ουρές25 template class Queue { private: int size; // μέγεθος της ουράς int front; // κατηγοριοποίηση του μπροστά στοιχείου int rear; // κατηγοριοποίηση του πίσω στοιχείου Elem *listarray; // πίνακας που κρατάει την λίστα των στοιχείων public: Queue(int sz = LIST_SIZE) { // κατασκευαστής size = sz + 1; front = rear = 0; listarray = new Elem[size]; } ~Queue( ) { delete [ ] listarray; } void clear( ) { front = rear; } // καθαρισμός ουράς void enqueue (const Elem); // enqueue στοιχείο στο τέλος του Elem dequeue( ); // dequeue στοιχείο από μπροστά του Elem firstValue( ) const // πάρε την τιμή του στοιχείου μπροστά { assert(!isEmpty( )); return listarray[(front+1) % size]; } bool isEmpty( ) const // ΑΛΗΘΕΙΑ αν η ουρά είναι άδεια { return front == rear; } }; μέγεθος μπροστά πίσω μέγεθος
Ε. ΠετράκηςΣτοίβες, Ουρές26 template void Queue ::enqueue(const Elem item) { assert(((rear+1) % size) != front);// η ουρά δεν πρέπει να είναι γεμάτη rear = (rear+1) % size; // αύξηση του πίσω(σε κύκλο) listarray[rear] = item; } template Elem Queue ::dequeue( ) { assert(!isEmpty()); front = (front+1) % size; // αύξηση του μπροστά return listarray[front]; // επέστρεψε την τιμή }
Ε. ΠετράκηςΣτοίβες, Ουρές27 Εφαρμογή Δυναμικής Μνήμης Απλή προσαρμογή της εφαρμογή της διασυνδεδεμένης λίστας Το τρέχων πάντα δείχνει το πρώτο στοιχείο Ο δείκτης κεφαλή της εφαρμογής λίστας δεν χρησιμοποιείται μπροστά πίσω
Ε. ΠετράκηςΣτοίβες, Ουρές28 template class Queue{//κλάση διασυνδεδεμένης ουράς private: link * front; // δείκτης στον μπροστά κόμβο της ουράς link * read; // δείκτης στον πίσω κόμβο της ουράς public: Queue( ) // κατασκευαστής: αρχικοποίηση { front = rear = NULL;} ~Queue( ) { clear( );}// καταστροφέας: επέστρεψε τη διεύθυνση του στοιχείου void clear( );// αφαίρεσε όλα τα στοιχεία από την ουρά void enqueue(const ELEM &);// enqueue στοιχείο πίσω ELEM dequeue( );// dequeue στοιχείο από μπροστά ELEM firstValue( ) const// πάρε την τιμή του μπροστά στοιχείου { assert(!isEmpty( )); return front element;} bool isEmpty( ) const// επέστρεψε ΑΛΗΘΕΙΑ αν η ουρά είναι άδεια { return front == NULL; };
Ε. ΠετράκηςΣτοίβες, Ουρές29 template void Queue ::clear( ) { //αφαίρεσε όλα τα στοιχεία while (front != NULL)//επέστρεψε τους συνδεδεμένους κόμβους σε ελεύθερη λίστα {rear = front; front = front next; delete rear;} rear = NULL; } template void Queue ::enqueue (const ELEM& item) { if (rear != NULL){ //η ουρά δεν είναι άδεια: προσθήκη στο τέλος rear next = new link (item,NULL); rear=rear next; } else front = rear = new link (item, NULL); //άδεια ουρά }
Ε. ΠετράκηςΣτοίβες, Ουρές30 template ELEM Queue ::dequeue( ) {// dequeue στοιχείο από μπροστά assert(!isEmpty( )); // πρέπει να υπάρχει στοιχείο για Dequeue ELEM temp=front element; //αποθήκευσε την dequeued τιμή link * ltemp = front;// κράτησε το σε ένα dequeued συνδεδεμένο κόμβο front=front next;// άλλαξε το μπροστά delete ltemp;// επέστρεψε τη διεύθυνση στην ελεύθερη λίστα if (front == NULL) rear = NULL; // dequeued τελευταίο στοιχείο return temp;// επέστρεψε τιμή του στοιχείου }
Ε. ΠετράκηςΣτοίβες, Ουρές31 Προτεραιότητα Ουράς Αύξουσα: τα στοιχεία είναι σε οποιαδήποτε σειρά αλλά η dequeue αφαιρεί το μικρότερο Φθίνουσα: η dequeue αφαιρεί το μέγιστο
Ε. ΠετράκηςΣτοίβες, Ουρές32 Ε D G Α μπροστά = 5 πίσω = 4 Ε D G μπροστά = 5 πίσω = 4 μπροστά = 5 πίσω = 4 αύξουσαφθίνουσα Ε D Α ? Παράδειγμα: Dequeue
Ε. ΠετράκηςΣτοίβες, Ουρές33 Εφαρμογή σε Πίνακα Πρόβλημα: η dequeue δημιουργεί άδειες θέσεις Λύση(1): μετακίνηση στοιχείων: Θ(n) πράξεις στην dequeue Λύση(2): αποθήκευση στοιχείων σε αυξουσά (φθίνουσα) σειρά: Θ(n) πράξεις στην enqueue Ε D G Α E D Α Ε D G Α E D Α