Ουρές
Ουρές
Περίληψη Η ΟυράΑΔΤ Υλοποίηση με κυκλικό πίνακα Αυξανόμενη Ουρά βασισμένη σε πίνακα Interface ουράς στην C++
Η Ουρά ADT Η ΑΔΤ Ουρά αποθηκεύει αυθαίρετα αντικείμενα Οι εισαγωγές και διαγραφές ακολουθούν το first-in first-out μοντέλο Οι εισαγωγές είναι στο πίσω της ουράς και οι διαγραφές στην αρχή της ουράς Βασικές λειτουργίες της ουράς: enqueue(object o): εισαγωγή στοιχείου o στο τέλος της ουράς dequeue(): αφαίρεση και επιστροφή του στοιχείου στην αρχή της ουράς Βοηθητικές λειτουργίες της ουράς: front(): επιστρέφει το στοιχείο στην αρχή χωρίς να το αφαιρεί size(): επιστρέφει τον αριθμό των στοιχείων isempty(): επιστρέφει μια Boolean τιμή που δείχνει αν υπάρχουν στοιχεία Exceptions Η εκτέλεση μιας dequeue ή front λειτουργίας σε μια άδεια ουρά προκαλεί EmptyQueueException
Ουρά (queue) Δομή τύπου FIFO: First In - First Out (πρώτη εισαγωγή πρώτη εξαγωγή) Περιορισμένος τύπος γραμμικής λίστας: Εισαγωγή στο ένα άκρο (στο τέλος) και διαγραφή από το άλλο (την αρχή) AbstractDataType Queue { instances ordered list of elements; one end is called the front; the other is the rear; operations Create (): create an empty queue; IsEmpty (): return true if queue is empty, return false otherwise; First (): return first (front) element of queue; Last (): return last (rear) element of queue; Add (x): add element x to the queue; Delete (x): delete front element from queue and put it in x; }
Εφαρμογές των Ουρών Άμεσες εφαρμογές Σειρές αναμονής Πρόσβαση σε μοιραζόμενους πόρους (π.χ., εκτυπωτής) Πολυπρογραμματισμός Έμμεσες εφαρμογές Βοηθητική δομή δεδομένων για αλγόριθμους Συστατικό άλλων δομών δεδομένων
Ουρά βασισμένη σε πίνακα Χρήση πίνακα μεγέθους N με κυκλικό τρόπο Δύο μεταβλητές καταγράφουν το μπροστά και το πίσω f δείκτης του μπροστινού στοιχείου r δείκτης αμέσως μετά το πίσω στοιχείο Η θέση r του πίνακα διατηρείται άδεια Q normal configuration 0 12 f r Q wrapped-around configuration 012 r f
Υλοποίηση ουράς με πίνακα location(i)=front+i-1 Ερωτήσεις: Γιατί να μη ξεκινά η ουρά πάντα από την αρχή του πίνακα; Τι πρόβλημα δημιουργείται με την ολίσθηση της ουράς προς τα δεξιά;
Λειτουργίες Ουράς Χρησιμοποιούμε την εντολή modulo (υπόλοιπο διαίρεσης) Algorithm size() return (N f + r) mod N Algorithm isempty() return (f r) Q Q 012 f r 012 r f
Λειτουργίες Ουράς (συνέχεια) Η εντολή enqueue προκαλεί exception αν ο πίνακας είναι γεμάτος Αυτό το exception είναι ανεξάρτητο υλοποίησης Algorithm enqueue(o) if size() = N 1 then throw FullQueueException else Q[r] o r (r + 1) mod N Q Q 012 f r 012 r f
Λειτουργίες Ουράς (συνέχεια) Η εντολή dequeue προκαλεί exception αν ο πίνακας είναι άδειος Algorithm dequeue() if isempty() then throw EmptyQueueException else o Q[f] f (f + 1) mod N return o Q 012 f r Q 012 r f
Υλοποίηση κυκλικής ουράς (με πίνακα) location(i)=(front+i)%maxsize Ερωτήσεις: Πού δείχνουν οι δείκτες front και rear; Πώς διακρίνουμε μεταξύ μιας άδειας και μιας γεμάτης ουράς;
Επαυξανόμενη Ουρά Βασισμένη σε Πίνακα Σε μια enqueue εντολή, όταν ο πίνακας είναι γεμάτος, αντί για πρόκληση exception, μπορούμε να αντικαταστήσουμε τον πίνακα με έναν μεγαλύτερο Παρόμοιο με αυτό που κάναμε στην βασισμένη σε πίνακα στοίβα Η enqueue εντολή έχει χρόνο απόσβεσης O(n) με την αυξητική στρατηγική O(1) με την στρατηγική διπλασιασμού
Συνδεδεμένη ουρά class LinkedQueue { // FIFO objects public: LinkedQueue() {front = rear = 0;}; // constructor ~LinkedQueue(); // destructor int IsEmpty() {return ((front)? 0 : 1);} int IsFull(); int First(type& x); // return first element of queue int Last(type& x); // return last element of queue int operator +(type x); // add x to queue int operator -(type& x); // delete x from queue // First,+,- return 0 on failure, 1 on success private: Node<type> *front, *rear; }
Προσθήκη (ως τελευταίο στοιχείο) σε συνδεδεμένη ουρά int LinkedQueue<type>::operator+(type x) //add x to queue { Node<type> *i; i = new Node<type>; if (i) { i->data = x; i->link = 0; if (front) rear->link = i; else front = i; rear = i; return 1; }; return 0; // add fails }
Διαγραφή (του πρώτου στοιχείου) από συνδεδεμένη ουρά int LinkedQueue<type>::operator-(type& x) //delete first element and return in x { if (IsEmpty()) return 0; //delete fails x = front->data; Node<type> *i = front; front = front->link; delete i; return 1; }
Άτυπο C++ Interface Ουράς Άτυπο C++ interface για την ADT ουρά Απαιτεί τον ορισμό της κλάσης EmptyQueueExceptio n template <typename Object> class Queue { public: int size(); bool isempty(); Object& front() throw(emptyqueueexception); void enqueue(object o); Object dequeue() throw(emptyqueueexception); };