Μάθημα 21: Ουρές (Queues)

Σχετικά έγγραφα
#4. Heaps (σωροί), η ταξινόμηση HeapSort, η δομή std::priority_queue της STL

Δομές Δεδομένων και Αλγόριθμοι

Standard Template Library (STL) C++ library

Μάθημα 22: Δυαδικά δέντρα (Binary Trees)

Δομές Δεδομένων (Data Structures)

Δομές Δεδομένων Standard Template Library (STL) 23/3/2017 ΜΠΟΜΠΟΤΑΣ ΑΓΟΡΑΚΗΣ

ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι 5. Αφηρημένοι Τύποι Δεδομένων / Στοίβες και Ουρές

Συλλογές, Στοίβες και Ουρές

Δομές Δεδομένων & Αλγόριθμοι

Διάλεξη 05: Αφηρημένοι Τύποι Δεδομένων

Εντολές εισόδου - εξόδου. Εισαγωγή στη C++

Βασικές Δομές Δεδομένων

Γ7.2 Συμβολοσειρές (Strings) Γ Λυκείου Κατεύθυνσης

Αλγόριθμοι και Δομές Δεδομένων (IΙ) (γράφοι και δένδρα)

Δομές Δεδομένων. Ενότητα 3: Ουρές Εισαγωγή-Υλοποίηση ΑΤΔ Ουρά με πίνακα. Καθηγήτρια Μαρία Σατρατζέμη. Τμήμα Εφαρμοσμένης Πληροφορικής.

Πανεπιστήμιο Πειραιώς Σχολή Τεχνολογιών Πληροφορικής και Επικοινωνιών Τμήμα Ψηφιακών Συστημάτων ομές εδομένων

Πανεπιστήμιο Πειραιώς Σχολή Τεχνολογιών Πληροφορικής και Επικοινωνιών Τμήμα Ψηφιακών Συστημάτων ομές εδομένων

Δομές Δεδομένων και Αλγόριθμοι

Δομές Επανάληψης. Εισαγωγή στη C++

Προγραμματισμός Υπολογιστών με C++

24ος ΠΑΝΕΛΛΗΝΙΟΣ ΔΙΑΓΩΝΙΣΜΟΣ ΠΛΗΡΟΦΟΡΙΚΗΣ

Δομές Δεδομένων & Ανάλυση Αλγορίθμων. 3ο Εξάμηνο. Ουρά (Queue) Υλοποίηση της με τη βοήθεια πίνακα.

Oι βασικές πράξεις (λειτουργίες) που ορίζονται για τον τύπο στοίβα αναφέρονται παρακάτω:

Πίνακες (Arrays) Εισαγωγή στη C++

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Δομές Δεδομένων και Αλγόριθμοι (Γ εξάμηνο) Τμήμα Μηχανικών Πληροφορικής ΤΕ, ΤΕΙ Ηπείρου. Άσκηση εργαστηρίου #6 (Υλοποίηση δυαδικού δένδρου αναζήτησης)

Δισδιάστατοι Πίνακες (2D Arrays) Εισαγωγή στη C++

Αλγόριθμοι Eλάχιστα μονοπάτια

Standard Template Library (STL)

Κατ οίκον Εργασία 5 Σκελετοί Λύσεων

Γράφοι. Ορολογία. Ορισµός: G = (V, E) όπου. Ορολογία (συνέχεια) γράφος ή γράφηµα (graph) V:ένα σύνολο E:µια διµελής σχέση στο V

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα προηγούμενα ακαδημαϊκά έτη: ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

Βασικές οµές εδοµένων

Η εντολή if-else. Η απλή μορφή της εντολής if είναι η ακόλουθη: if (συνθήκη) { Η γενική μορφή της εντολής ifelse. εντολή_1; εντολή_2;..

Οι βασικές λειτουργίες (ή πράξεις) που γίνονται σε μια δομή δεδομένων είναι:

Σύνοψη Προηγούμενου (1/2) Στοίβες, Ουρές, Ουρές Προτεραιότητας. Σύνοψη Προηγούμενου (2/2) Σημερινό Μάθημα. Πίνακες. Εισαγωγή, σε χρόνο O(1).

Διορθώσεις σελ

19. ΠΡΟΤΥΠΑ (TEMPLATES)

ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΚΑΙ ΠΙΝΑΚΕΣ

Δομές Δεδομένων. Ενότητα 2: Στοίβες Εισαγωγή-Υλοποίηση ΑΤΔ Στοίβα με Πίνακα-Εφαρμογή Στοίβας: Αντίστροφη Πολωνική Γραφή. Καθηγήτρια Μαρία Σατρατζέμη

Προγραμματισμός Υπολογιστών με C++

Οντοκεντρικός Προγραμματισμός

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ Κεφάλαιο 3 ο

ιαφάνειες παρουσίασης #11

Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Υλοποίηση Λιστών. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα:

Δομές Δεδομένων. Ενότητα 6: Εφαρμογή Συνδεδεμένων Λιστών: Αλφαβητικό ευρετήριο κειμένου- Υλοποίηση ΑΤΔ Στοίβα και Ουρά με δείκτες

Τύποι Δεδομένων και Απλές Δομές Δεδομένων. Παύλος Εφραιμίδης V1.0 ( )

Σχεδίαση & Ανάλυση Αλγορίθμων

ΕΡΓΑΣΤΗΡΙΟ 5 ΣΗΜΕΙΩΣΕΙΣ

ΑΝΑΠΤΥΞΗ ΕΦΑΡΜΟΓΩΝ ΣΕ ΠΡΟΓΡΑΜΜΑΤΙΣΤΙΚΟ ΠΕΡΙΒΑΛΛΟΝ

Προηγµένα Θέµατα Τεχνολογιών Υλοποίησης Αλγορίθµων

Τεχνολογίες Υλοποίησης Αλγορίθµων

Συμβολοσειρές ΣΥΜΒΟΛΟΣΕΙΡΕΣ. Γεώργιος Παπαϊωάννου ( )

Διάλεξη 12: Λίστες Υλοποίηση & Εφαρμογές. Διδάσκων: Παναγιώτης Ανδρέου

Δομές Δεδομένων & Αλγόριθμοι

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τύποι δεδομένων ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ ΠΡΑΞΕΙΣ ΜΕΤΑΒΛΗΤΕΣ. Ακέραιοι αριθμοί (int) Πράξεις μεταξύ ακεραίων αριθμών

Αφηρημένες Δομές Δεδομένων. Στοίβα (Stack) Υλοποίηση στοίβας

Προγραμματισμός Υπολογιστών με C++

Δομές Δεδομένων. Λουκάς Γεωργιάδης.

Οντοκεντρικός Προγραμματισμός

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις

Γράφοι: κατευθυνόμενοι και μη

ΛΥΣΕΙΣ ΘΕΜΑΤΩΝ ΤΕΛΙΚΗΣ ΦΑΣΗΣ

Φροντιςτήριο. Linked-List

Ονοματεπώνυμο και ΑΜ: Είχα παραδώσει εργασίες τα εξής ακαδημαϊκά έτη: Διάρκεια: 2,5 ώρες, κλειστά βιβλία και σημειώσεις ΚΑΛΗ ΕΠΙΤΥΧΙΑ!

ΠΛΗ111. Ανοιξη Μάθηµα 5 ο. Ουρά. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

Σύνοψη Προηγούμενου. Λίστες (Lists) Συνδεδεμένες Λίστες: Εισαγωγή (1/2) Συνδεδεμένες Λίστες. Ορέστης Τελέλης

Διάλεξη 26: Σωροί. Διδάσκων: Παναγιώτης Ανδρέου

Δομές Δεδομένων Ενότητα 4

Ελαφρύτατες διαδρομές

Ενότητα 5: Αλγόριθμοι γράφων και δικτύων

Προγραμματισμός Ι. Κλάσεις και Αντικείμενα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ΠΛΗ111. Ανοιξη Μάθηµα 4 ο. Στοίβα. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Τύποι δεδομένων, μεταβλητές, πράξεις. Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Red-Black Δέντρα. Red-Black Δέντρα

Προγραμματισμός Η/Υ. 4 η ενότητα: Δομές Δεδομένων. Τμήμα. Τεχνολόγων Περιβάλλοντος. ΤΕΙ Ιονίων Νήσων. Ανοικτά Ακαδημαϊκά Μαθήματα στο ΤΕΙ Ιονίων Νήσων

Στοίβες - Ουρές. Στοίβα (stack) Γιάννης Θεοδωρίδης, Νίκος Πελέκης, Άγγελος Πικράκης Τµήµα Πληροφορικής

ΑΣΚΗΣΕΙΣ ΓΙΑ ΤΟ ΕΡΓΑΣΤΗΡΙΟ 1

Δομές Δεδομένων. Ενότητα 10: Πλήρη Δυαδικά Δέντρα, Μέγιστα/Ελάχιστα Δέντρα & Εισαγωγή στο Σωρό- Ο ΑΤΔ Μέγιστος Σωρός. Καθηγήτρια Μαρία Σατρατζέμη

Αλγόριθμοι Γραφημάτων

Διάλεξη 9: Αφηρημένοι Τύποι Δεδομένων. Διδάσκων: Παναγιώτης Ανδρέου

ΕΝΟΤΗΤΑ 7 ΟΥΡΕΣ ΠΡΟΤΕΡΑΙΟΤΗΤΑΣ ΣΩΡΟΙ

Αναζήτηση σε Γράφους. Μανόλης Κουμπαράκης. ΥΣ02 Τεχνητή Νοημοσύνη 1

Οντοκεντρικός Προγραμματισμός

POINTERS, AGGREGATION, COMPOSITION

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Δομές Δεδομένων. Λουκάς Γεωργιάδης.

Γ7.5 Αλγόριθμοι Αναζήτησης. Γ Λυκείου Κατεύθυνσης

Γ7.1 Επανάληψη ύλης Β Λυκείου. Γ Λυκείου Κατεύθυνσης

Ουρά Προτεραιότητας (priority queue)

ΥΠΟΛΟΓΙΣΤΕΣ ΙI. Άδειες Χρήσης. Δομή του προγράμματος. Διδάσκοντες: Αν. Καθ. Δ. Παπαγεωργίου, Αν. Καθ. Ε. Λοιδωρίκης

Τίτλος Μαθήματος: Ηλεκτρονικοί Υπολογιστές IΙΙ. Διδάσκων: Επίκουρος Καθηγητής Αθανάσιος Σταυρακούδης

ΥΠΟΛΟΓΙΣΤΕΣ ΙΙ. Τι περιλαμβάνει μια μεταβλητή; ΔΕΙΚΤΕΣ. Διεύθυνση μεταβλητής. Δείκτης

Υπολογιστικά Mαθηματικά II

Βασικές Έννοιες Δοµών Δεδοµένων

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

Transcript:

Queues Page 1 Μάθημα 21: Ουρές (Queues) Η ουρά (queue) είναι μια δομή δεδομένων. Η βασική λειτουργικότητα είναι η εισαγωγή στοιχείων στην πίσω θέση και η εξαγωγή-διαγραφή στοιχείων από την μπροστινή θέση. Με αυτόν τον τρόπο, η ουρά είναι μια FIFO (First-In-First-Out, Πρώτο-Μέσα-Πρώτο-Έξω) δομή δεδομένων. Σε μια FIFO δομή δεδομένων, το πρώτο στοιχείο που εισάγεται στην ουρά θα είναι το πρώτο που θα αφαιρεθεί-εξυπηρετηθεί. Ουρές δεδομένων μπορούν να δημιουργηθούν με την χρήση του queue της πρότυπης βιβλιοθήκης (STL) της C++. Ορίζεται στο αρχείο επικεφαλίδας <queue> και η βασική λειτουργικότητά του είναι η δυνατότητα εισαγωγής στοιχείων στο πίσω μέρος της δομής και εξαγωγή στοιχείων από την αρχή του. Η βιβλιοθήκη <queue> παρέχει δύο είδη ουρών: Απλή ουρά δεδομένων όπου όλα τα στοιχεία εξυπηρετούνται με την σειρά που μπήκαν. Ουρά δεδομένων με δυνατότητα επιλογής προτεραιότητας (priority queue). Στην ουρά αυτή τα νέα στοιχεία που εισάγονται με προτεραιότητα τοποθετούνται μπροστά από όλα τα στοιχεία μικρότερης προτεραιότητας. Μέθοδοι Συνήθεις μέθοδοι από την βιβλιοθήκη queue για απλές ουρές και ουρές προτεραιότητας είναι οι: push(item) Εισαγωγή στοιχείου στην ουρά. Συγκεκριμένα εισάγει το αντικείμενο item στο πίσω μέρος της ουράς. Στην ουρά προτεραιότητας το στοιχείο τοποθετείται μέσα στην ουρά με βάση την προτεραιότητα που έχει. front() pop() back() top() empty() size() Επιστρέφει το πρώτο στοιχείο της ουράς χωρίς να το αφαιρέσει. Διαγράφει/αφαιρεί το στοιχείο που βρίσκεται στην αρχική/μπροστινή θέση μιας μη άδειας ουράς. Για την επιστροφή του στοιχείου αυτού θα πρέπει νωρίτερα να χρησιμοποιηθεί η front(). Επιστρέφει το τελευταίο στοιχείο της ουράς χωρίς να το αφαιρέσει. Επιστρέφει το στοιχείο με την μεγαλύτερη προτεραιότητα (για ουρές προτεραιότητας) χωρίς να το αφαιρέσει. Επιστρέφει True (αληθές) αν η ουρά είναι άδεια και False διαφορετικά. Επιστρέφει το συνολικό πλήθος των στοιχείων της ουράς.

Queues Page 2 Παράδειγμα 1 Ποιο θα είναι το αποτέλεσμα μετά την εκτέλεση του πιο κάτω κώδικα; #include <queue> #include <iostream> using namespace std; int main(){ queue< char > Q; Q.push('a'); Q.push('b'); Q.push('c'); Q.push('A'); Q.push('B'); Q.push('C'); cout << Q.front() << endl; cout << Q.back() << endl; Q.pop(); Q.pop(); while(!q.empty()) { cout << Q.size() << endl; cout << Q.front() << endl; Q.pop(); return 0; Ουρά προτεραιοτήτων (Priority Queue) Στην ουρά προτεραιότητας κατά την λειτουργία top()-pop() για να επιλεχθεί το στοιχείο με την προτεραιότητα συγκρίνονται όλα τα στοιχεία της ουράς με το τελεστή μικρότερο < και εξάγεται το μεγαλύτερο στοιχείο (μεγαλύτερη προτεραιότητα). Μπορούμε επίσης να ορίσουμε τη δική μας συνάρτηση ελέγχου προτεραιότητας. Παράδειγμα 2 Ποιο θα είναι το αποτέλεσμα μετά την εκτέλεση του πιο κάτω κώδικα; #include <queue> #include <iostream> using namespace std; int main() { priority_queue<int> pq; pq.push(120); pq.push(67);

Queues Page 3 pq.push(112); pq.push(23); pq.push(56); pq.push(94); pq.push(256); while (!pq.empty()) { cout << pq.top() << " "; pq.pop(); return 0; Παράδειγμα 3 Ποιο θα είναι το αποτέλεσμα μετά την εκτέλεση του πιο κάτω κώδικα; #include <iostream> #include <queue> using namespace std; int main(){ priority_queue <int, vector<int>, greater<int> > pq; pq.push(2); pq.push(5); pq.push(3); pq.push(1); pq.push(4); while (!pq.empty()) { cout << pq.top() << endl; pq.pop(); return 0; deque Το deque είναι ένα container όμοιο σε δυνατότητες με ένα vector. Η διαφορά τους είναι ότι, σε αντίθεση με το vector που επιτρέπει την εισαγωγή και διαγραφή στοιχείων μόνο στο τέλος (push_back(), pop_back()) το deque παρέχει αυτή τη δυνατότητα και στα δύο άκρα (push_back(), push_front(), pop_back(), pop_front()). Χρησιμοποιεί όλες τις υπόλοιπες συναρτήσεις που παρέχει το vector.

Queues Page 4 Παράδειγμα 4 #include <deque> #include <iostream> using namespace std; int main() { deque<int> d; for (int i = 0; i<10; i++) d.push_front(i); for (int i = 10; i < 20; i++) d.push_back(i); int f = d.front(); int b = d.back(); cout << "front element is " << f << endl; cout << "back element is " << b << endl; for (deque<int>::iterator it=d.begin(); it!=d.end(); ++it) cout << *it << " "; return 0; Αλγόριθμος BFS Ο Αλγόριθμος BFS υλοποιείται πολύ εύκολα με την STL χρησιμοποιώντας τα queue και map. Το queue αποθηκεύει τη σειρά με την οποία επισκεφτήκαμε τους κόμβους ενώ το map αν έχουμε επισκεφτέι ένα κόμβο καθώς και την απόσταση από τον κόμβο-αφετηρία. Αρχικά δηλώνουμε: #define TRvii(c, it) \ for (vii::iterator it = c.begin(); it!= c.end(); it++) typedef pair<int, int> ii; typedef vector<ii> vii; vector<vii> AdjList;

Queues Page 5 //BFS algorithm queue<int> q; map<int, int> dist; q.push(s); dist[s] = 0; while (!q.empty()){ int u = q.front(); q.pop(); TRvii (AdjList[u], it) // traverse each neighbour of u if (!dist.count(it->first)) { dist[it->first] = dist[u] + 1; q.push(it->first); Input: 13 16 10 15 15 20 20 25 10 30 30 47 47 50 25 45 45 65 15 35 35 55 20 40 50 55 35 40 55 60 40 60 60 65 Output: Distance: 0, Visited: 35 Distance: 1, Visited: 15 55 40 Distance: 2, Visited: 10 20 50 60 Distance: 3, Visited: 30 25 47 65 Distance: 4, Visited: 45 Path: 35 15 10 30 Αλγόριθμος του Dijkstra Με τη χρήση του priority queue μπορούμε να υλοποιήσουμε τον αλγόριθμο του Dijkstra. vector<int> dist(v, INF); dist[s] = 0; priority_queue<ii, vector<ii>, greater<ii> > pq; pq.push(ii(0, s)); while (!pq.empty()){ ii top = pq.top(); pq.pop(); int d = top.first, u = top.second; if (d == dist[u]) TRvii (AdjList[u], it){ int v = it->first, weight = it->second; if (dist[u] + weight < dist[v]) { dist[v] = dist[u] + weight; pq.push(ii(dist[v], v));

Queues Page 6 Input: 5 7 2 1 2 2 3 7 2 5 6 1 3 3 1 4 6 3 4 5 5 4 1 Output: Shortest Path(2,1)= 2 Shortest Path(2,2)= 0 Shortest Path(2,3)= 5 Shortest Path(2,4)= 7 Shortest Path(2,5)= 6 Επεξήγηση: 1. Στην αρχή έχουμε: dist[source] = dist[2] = 0, το pq είναι η ακμή {(0,2). 2. Από τον κόμβο 2, ελέγχουμε τους κόμβους {1, 3, 5. Τώρα dist[1] = 2, dist[3] = 7, και dist[5] = 6. Το περιεχόμενο του pq είναι οι {(2,1), (6,5), (7,3). 3. Ανάμεσα στους {1, 5, 3 μέσα στο pq, ο κόμβος 1 έχει το μικρότερο dist[1] = 2 και είναι στην κορυφή του pq. Αφαιρούμε το (2,1) και ελέγχουμε τους γείτονες: {3, 4 έτσι ώστε το dist[3] = min(dist[3], dist[1]+weight(1,3)) = min(7, 2+3) = 5 και dist[4] = 8. Τώρα το pq περιέχει τα {(5,3), (6,5), (7,3), (8,4). Βλέπουμε ότι υπάρχει δύο φορές ο κόμβος 3. Δεν μας επηρεάζει καθώς ο Dijkstra s θα επιλέξει το ζεύγος με το μικρότερο βάρος. 4. Αφαιρούμε το (5,3) και δοκιμάζουμε το (3,4), αλλά 5+5 = 10, ενώ dist[4] = 8 (από το μονοπάτι (2-1-4). Έτσι το dist[4] δεν αλλάζει. Το pq περιέχει τα {(6,5), (7,3), (8,4). 5. Αφαιρούμε το (6,5) και δοκιμάζουμε το (5, 4), αλλάζοντας το dist[4] = 7 (το συντομότερο μονοπάτι από το 2 στο 4 είναι τώρα το 2-5-4 αντί το 2-1-4). Το pq περιέχει τα {(7,3), (7,4), (8,4).

Queues Page 7 6. Ακολούθως, το (7,3) μπορεί να αγνοηθεί καθώς γνωρίζουμε ότι d > dist[3] (7 > 5). Μετά ελέγχουμε το (7,4) όπως προηγουμένως. Τέλος, η το (8,4) θα αγνοηθεί καθώς το d > dist[4] (8 > 7). Ο Dijkstra s σταματά καθώς το priority queue έχει αδειάσει. Αλγόριθμος Bellman Ford s Αν ο γράφος έχει αρνητικά βάρη ο αλγόριθμος του Dikstra πιθανόν να αποτύχει. Για παράδειγμα στον πιο κάτω γράφο ο Dijkstra αποτυγχάνει. Γιατί; Για γράφους με αρνητικά βάρη χρησιμοποιούμε τον αλγόριθμο Bellman Ford. Δουλεύει ακόμα και με αρνητικά βάρη ακμών Επισκέπτεται όλες τις ακμές V-1 φορές Η επανάληψη i βρίσκει όλα τα συντομότερα μονοπάτια που χρησιμοποιούν i ακμές Αν ο γράφος μας δεν είναι άκυκλος πρέπει να ελέγχουμε για αρνητικούς κύκλους (negative cycles). vector<int> dist(v, INF); dist[s] = 0; REP (i, 0, V - 1) REP (u, 0, V - 1) TRvii (AdjList[u], it) dist[it->first] = min(dist[it->first], dist[u] + it->second); bool negative_cycle_exist = false;

Queues Page 8 REP (u, 0, V - 1) TRvii (AdjList[u], it) if (dist[it->first] > dist[u] + it->second) negative_cycle_exist = true; if (!negative_cycle_exist) REP (i, 0, V - 1) cout << s << "->" << i<< "=" << dist[i] << endl;