Professional Documents
Culture Documents
2 Stacks
2 Stacks
Οι διαφάνειες είναι βασισμένες στο βιβλίο "Data Structures and Algorithms in C++" των Michael T. Goodrich, Roberto Tamassia και David M. Mount
Περίληψη
Ο ADT σωρός (§4.2.1)
Εφαρμογές των σωρών (§4.2.3)
Array-based υλοποίηση (§4.2.2)
Growable array-based σωρός
Σωροί 2
Abstract Data Types (ADTs)
Ένα ADT είναι μια Παράδειγμα: ADT μοντελοποίηση
αφαίρεση μιας απλού χρηματιστηριακού
δομής δεδομένων συστήματος
Τα δεδομένα είναι buy/sell εντολές
Ένα ADT ορίζει:
Σωροί 3
The Stack ADT
O ADT Σωρός αποθηκεύει Βοηθητικές λειτουργίες
αυθαίρετα αντικείμενα του σωρού:
Οι εισαγωγές και top(): επιστρέφει το
διαγραφές ακολουθούν το τελευταία εισαγμένο
στοιχείο χωρίς να το
last-in first-out μοντέλο αφαιρεί
Βασικές λειτουργίες του size(): επιστρέφει τον
σωρού: αριθμό τον
push(Object o): εισάγει το αποθηκευμένων στοιχείων
στοιχείο o isEmpty(): Boolean τιμή
pop(): αφαιρεί και που δείχνει αν υπάρχουν
επιστρέφει το τελευταία αποθηκευμένα στοιχεία
εισαγμένο στοιχείο
Σωροί 4
Exceptions
Η απόπειρα εκτέλεσης Στον σωρό ADT, οι
μιας λειτουργίας σε ADT λειτουργίες pop και
μπορεί να προκαλέσει
top δεν μπορούν να
συνθήκες λαθών, που
ονομάζονται exceptions εκτελεστούν αν ο
Οι Exceptions λέγεται ότι σωρός είναι άδειος
γίνονται “thrown” από μια Η απόπειρα
λειτουργία που δεν μπορεί εκτέλεσης της pop ή
να εκτελεστεί top σε άδειο σωρό
προκαλεί την
EmptyStackException
Σωροί 5
Εφαρμογές των Σωρών
Άμεσες εφαρμογές
Ιστορικό σελίδων σε Web browser
Ακολουθία undo σε επεξεργαστή κειμένου
Έμμεσες εφαρμογές
Βοηθητική δομή δεδομένων για
αλγόριθμους
Συστατικό άλλων δομών δεδομένων
Σωροί 6
C++ Run-time Σωρός
Το C++ run-time system καταγράφει main() {
την αλυσίδα των ενεργών int i = 5; bar
συναρτήσεων στο σωρό foo(i); PC = 1
Όταν μια συνάρτηση καλείται, το run- } m=6
time system σπρώχνει στον σωρό ένα
πλαίσιο που περιέχει foo(int j) {
foo
Τοπικές μεταβλητές και τιμή int k; PC = 3
επιστροφής k = j+1; j=5
Program counter, που καταγράφει την
bar(k); k=6
εντολή που εκτελείται
}
Όταν μια συνάρτηση επιστρέφει, το
main
πλαίσιό της αφαιρείται από τον σωρό bar(int m) { PC = 2
και ο έλεγχος περνάει στην μέθοδο
στην κορυφή του σωρού
… i=5
}
Σωροί 7
Array-based Σωρός
Ένας απλός τρόπος για Algorithm size()
την υλοποίηση ADT return t + 1
σωρού με χρήση
πινάκων
Algorithm pop()
Προσθέτουμε στοιχεία
από αριστερά προς τα
if isEmpty() then
δεξιά throw EmptyStackException
Μια μεταβλητή else
καταγράφει τον δείκτη tt1
του κορυφαίου στοιχείου return S[t + 1]
…
S
0 1 2 t
Σωροί 8
Array-based Σωρός (συνέχεια)
Ο πίνακας που περιέχει
τα στοιχεία του σωρού Algorithm push(o)
μπορεί να γεμίσει if t = S.length 1 then
Μια push εντολή θα throw FullStackException
προκαλέσει τότε μια else
FullStackException tt+1
Περιορισμός της array- S[t] o
based υλοποίησης
…
S
0 1 2 t
Σωροί 9
Απόδοση και Περιορισμοί
Απόδοση
Έστω n ο αριθμός των στοιχείων στον σωρό
Ο χώρος που χρησιμοποιείται είναι O(n)
Κάθε λειτουργία εκτελείται σε χρόνο O(1)
Περιορισμοί
Το μέγιστο μέγεθος του σωρού πρέπει να οριστεί
a priori , και δεν μπορεί να αλλάξει
Η απόπειρα εισαγωγής νέου στοιχείου σε γεμάτο
σωρό προκαλεί exception
Σωροί 10
Computing Spans
7
Δείχνουμε πως 6
χρησιμοποιείται ένας σωρός 5
σαν βοηθητική δομή
δεδομένων σε αλγόριθμο 4
Δεδομένου πίνακα X, το span 3
S[i] του X[i] είναι ο μέγιστος 2
αριθμός συνεχών στοιχείων 1
X[j] που προηγούνται άμεσα 0
του X[i] και τέτοια ώστε X[j]
X[i] 0 1 2 3 4
Εφαρμογή σε οικονομική
ανάλυση X 6 3 4 5 2
Π.χ., μετοχή σε 52-week high S 1 1 2 3 1
Σωροί 11
Quadratic Αλγόριθμος
Algorithm spans1(X, n)
Input array X of n integers
Output array S of spans of X #
S new array of n integers n
for i 0 to n 1 do n
s1 n
while s i X[i s] X[i] 1 2 … (n 1)
ss1 1 2 … (n 1)
S[i] s n
return S 1
Σωροί 13
Γραμμικός Αλγόριθμος
Κάθε δείκτης του Algorithm spans2(X, n) #
πίνακα S new array of n integers n
Προστίθεται στον A new empty stack 1
σωρό ακριβώς μια
φορά for i 0 to n 1 do n
Αφαιρείται από τον while (A.isEmpty()
σωρό το πολύ μια X[top()] X[i] ) do n
φορά j A.pop() n
Οι δηλώσεις στο if A.isEmpty() then n
while-loop S[i] i 1 n
εκτελούνται το else
πολύ n φορές S[i] i j n
Ο αλγόριθμος A.push(i) n
spans2 εκτελείται return S 1
σε χρόνο O(n)
Σωροί 14
Επεκτεινόμενος Array-based Σωρός
Σε μια push λειτουργία, όταν ο Algorithm push(o)
πίνακας είναι γεμάτος, αντί για if t = S.length 1 then
δημιουργία exception, A new array of
μπορούμε να αντικαταστήσουμε size …
τον πίνακα με έναν μεγαλύτερο for i 0 to t do
Πόσο μεγάλος πρέπει να είναι ο A[i] S[i]
νέος πίνακας; SA
αυξητική στρατηγική: αύξηση
tt+1
μεγέθους με σταθερά c S[t] o
στρατηγική διπλασιασμού:
διπλασιασμός του μεγέθους
Σωροί 15
Σύγκριση Στρατηγικών
Συγκρίνουμε την αυξητική στρατηγική και
την στρατηγική διπλασιασμού αναλύοντας
τον συνολικό χρόνο T(n) που χρειάζεται για
να εκτελεστεί μια σειρά από n λειτουργίες
push
Υποθέτουμε ότι ξεκινάμε με ένα άδειο σωρό
που αναπαριστάται με πίνακα μεγέθους 1
Ονομάζουμε αποσβενούμενο χρόνο μίας
push λειτουργίας τον μέσο χρόνο T(n)/n
Σωροί 16
Ανάλυση της Αυξητικής Στρατηγικής
Σωροί 17
Ανάλυση της Στρατηγικής Διπλασιασμού
Αντικαθιστούμε τον πίνακα k =
log2 n φορές
γεωμετρική σειρά
Ο συνολικός χρόνος T(n) μιας
σειράς από n push λειτουργίες 2
είναι ανάλογος με 4
n + 1 + 2 + 4 + 8 + …+ 2k = 1 1
n 2k + 1 1 = 2n 1
8
T(n) είναι O(n)
Ο αποσβενούμενος χρόνος της
push λειτουργίας είναι O(1)
Σωροί 18
Stack Interface στη C++
template <typename Object>
Interface
class Stack {
ανταποκρινόμενο
public:
στον ADT Σωρό int size();
Απαιτεί τον ορισμό bool isEmpty();
της κλάσης Object& top()
EmptyStackException throw(EmptyStackException);
Παρόμοιο STL void push(Object o);
construct είναι το Object pop()
vector throw(EmptyStackException);
};
Σωροί 19
Array-based Stack στη C++
template <typename Object> bool isEmpty()
class ArrayStack { { return (t < 0); }
private:
int capacity; // stack capacity Object pop()
Object *S; // stack array throw(EmptyStackException) {
int top; // top of stack if(isEmpty())
public: throw EmptyStackException
ArrayStack(int c) { (“Access to empty stack”);
capacity = c; return S[t--];
S = new Object[capacity]; }
t = –1; // … (other functions omitted)
}
Σωροί 20