Προγραμματισμός Υπολογιστών με C++ ( 2012-1 ) 16η διάλεξη Ίων Ανδρουτσόπουλος http://www.aueb.gr/users/ion/ 1
Τι θα ακούσετε σήμερα Υλοποίηση στοίβας ακεραίων με χρήση τάξεων, δυναμικής καταχώρισης μνήμης και σχεδιοτύπων. Γενικευμένη υλοποίηση στοίβας με χρήση σχεδιοτύπων τάξεων. 2
Στοίβα ( push( ( push( () pop i = κενή στοίβα Το i γίνεται.
Μια πρώτη παράσταση στοίβας top αντικείμενα της τάξης StackNode 10 Παράσταση κενής στοίβας: top 0 0 4
Η τάξη StackNode class StackNode { const int i; const StackNode* const next; public: int getvalue() const { return i; const StackNode* const getnext() const { return next; StackNode(const int iin, const StackNode* const nextin = 0) : i(iin), next(nextin) { ; 5
Παράδειγμα χρήσης της StackNode int main() { StackNode n1(), n2(, &n1), n(10, &n2); n 10 n2 n1 0 0 6
Βελτίωση: η τάξη Stack class Stack { const StackNode* top; void deletestacknodes(); static const StackNode* const copystacknodes( const StackNode* const originalptr); public: StackNode n bool isempty() const { return (top = = 0); 10 void push(int i); Stack s1 int pop(); StackNode n2 top: Stack() : top(0) { ~Stack() { deletestacknodes(); StackNode n1 Stack(const Stack& original); Stack& operator=(const Stack& right); ; 0
Παράδειγμα χρήσης της Stack int main() { Stack s1; s1.push(); s1.push(); s1.push(10); Stack s2(s1); s2.push(20); cout << s1.pop() << endl; // Τυπώνει 10. s1 = s2; cout << s1.pop() << endl; // Τυπώνει 20. cout << s2.pop() << endl; // Τυπώνει 20. Ο χρήστης της Stack δεν χρειάζεται να γνωρίζει πώς έχει υλοποιηθεί εσωτερικά η στοίβα (π.χ. ότι χρησιμοποιούνται δείκτες, πώς μεταβάλλονται κλπ). 8
Stack: η μέθοδος push void Stack::push(const int i) { newtop const StackNode* const newtop = new StackNode(i, top); top = newtop; ( push(2 n s1 10 top: n2 2 n1 0 9
Stack: η μέθοδος pop int Stack::pop() { if(isempty()) { return 0; const int value = top->getvalue(); const StackNode* const newtop = top->getnext(); s1 delete top; top: top = newtop; return value; newtop n 10 n2 n1 0 10
Stack: η μέθοδος deletestacknodes void Stack::deleteStackNodes() { const StackNode* newtop; while(top!= 0) { newtop = top->getnext(); delete top; top = newtop; s1 top: newtop n 10 n2 n1 0 11
Stack: η copystacknodes originalptr 10 copyptr 10 originalnext copynext 0 0 Αναδρομική αντιγραφή μικρότερου μέρους της αλυσίδας. 12
Stack: η copystacknodes const StackNode* const Stack::copyStackNodes( const StackNode* const originalptr) { // Αν δεν υπάρχει τίποτα να αντιγράψουμε: if(originalptr = = 0) { return 0; const StackNode* const originalnext = originalptr->getnext(); const StackNode* const copynext = copystacknodes(originalnext); const StackNode* const copyptr = new StackNode(originalPtr->getValue(), copynext); return copyptr; 1
Η copystacknodes συντομότερα const StackNode* const Stack::copyStackNodes( const StackNode* const originalptr) { if(originalptr = = 0) { return 0; return new StackNode(originalPtr->getValue(), copystacknodes(originalptr->getnext())); 14
Stack: κατασκευαστής αντιγραφής και τελεστής εκχώρησης Stack::Stack(const Stack& original) : top(copystacknodes(original.top)) { Stack& Stack::operator=(const Stack& right) { if(this = = &right) { return *this; deletestacknodes(); top = copystacknodes(right.top); return *this; 15
Γενίκευση της Stack: τρόπος χρήσης int main() { Stack<string> s; s.push("seven"); s.push("three"); s.push("ten"); Stack<string> s4(s); s4.push("twenty"); cout << s.pop() << endl; s = s4; cout << s.pop() << endl; cout << s4.pop() << endl; 16
Γενίκευση της StackNode template <typename Type> class StackNode { const Type i; const StackNode* const next; public: const Type getvalue() const { return i; const StackNode* const getnext() const { return next; StackNode(const Type iin, const StackNode* const nextin = 0) : i(iin), next(nextin) { ; 1
Γενίκευση της Stack template <typename Type> class Stack { const StackNode<Type>* top; void deletestacknodes(); static const StackNode<Type>* const copystacknodes( const StackNode<Type>* const originalptr); public: bool isempty() const { return (top == 0); void push(type i); Type pop(); Stack() : top(0) { ~Stack() { deletestacknodes(); Stack(const Stack& original); Stack& operator=(const Stack& right); ; 18
Γενίκευση μεθόδων της Stack template <typename Type> void Stack<Type>::push(Type i) { const StackNode<Type>* const newtop = new StackNode<Type>(i, top); top = newtop; Ομοίως τροποποιούμε και τις άλλες μεθόδους. 19