ΠΛΗ οµηµένος Προγραµµατισµός Ανοιξη 5 Μάθηµα 5 ο Ουρά Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης
Ανασκόπηση Αφηρηµένος Τύπος εδοµένων Ουρά Υλοποίηση µε Κυκλικό Πίνακα Υλοποίηση µε Συνδεδεµένη Λίστα Εφαρµογές Ανοιξη 5 Στέργιος Β. Αναστασιάδης
Αφηρηµένος Τύπος εδοµένων Ουρά Γραµµική συλλογή στοιχείων Η εισαγωγή γίνεται στο ένα άκρο (rear, ) και η διαγραφή στο άλλο άκρο (front, ) FIFO (First In First Out) Παράδειγµα: ουρά αναµονής σε εµπορικά, υπηρεσίες dequeue enqueue Ανοιξη 5 Στέργιος Β. Αναστασιάδης 3
Βασικές Πράξεις Ουράς create() : δηµιουργεί κενή ουρά empty() : ελέγχει αν µια ουρά είναι κενή () : επιστρέφει το πρώτο στοιχείο της ουράς enqueue() : εισάγει στοιχείο στην ουρά () dequeue() : αποµακρύνει στοιχείο από την ουρά () Γ Β Α Ανοιξη 5 Στέργιος Β. Αναστασιάδης 4
Χρησιµοποιούµε Υλοποίηση Ουράς µε Πίνακα Κυκλικό πίνακα είκτες στην αρχή και το τέλος της ουράς Συνθήκη διάκρισης µεταξύ άδειας και γεµάτης ουράς N- Ανοιξη 5 Στέργιος Β. Αναστασιάδης 5
Ορισµός Κυκλικού Πίνακα #define N /* µέγεθος πίνακα */ typedef struct { int queue[n]; int, ; queue_t, *queueptr_t; queue_t queue; N- void create(queueptr_t q) { q-> = q-> = ; Ανοιξη 5 Στέργιος Β. Αναστασιάδης 6
Ακραίες Συνθήκες /* έλεγχος άδειας ουράς */ N- int empty(queueptr_t q) { return (q-> == q->); /* έλεγχος γεµάτης ουράς */ int full(queueptr_t q) { N- return ((q-> + ) % N == q->); unused slot! Ανοιξη 5 Στέργιος Β. Αναστασιάδης 7
Προσθήκη/Αποµάκρυνση Στοιχείου void enqueue(queueptr_t q, data_t d) { if (full(q)) printf( full queue ); else { /* προσθήκη στοιχείου */ q->queue[q->] = d; q-> = (q-> + ) % N; void dequeue(queueptr_t q, data_t *d) { if (empty(q)) printf( empty queue ); else { /* αποµάκρυνση στοιχείου */ *d = q->queue[q->]; q-> = (q-> + ) % N; N- N- Ανοιξη 5 Στέργιος Β. Αναστασιάδης 8
Υλοποίηση µε Λογική Μεταβλητή Για να µη µένει αχρησιµοποίητο ένα στοιχείο στη διάκριση κενής και γεµάτης ουράς εισάγουµε µια λογική µεταβλητή empty µε αρχική τιµή στη δοµή queue_t N- int empty(queueptr_t q) { return(q->empty); int full(queueptr_t q) { return((q-> == q->) && (!q->empty)); N- Ανοιξη 5 Στέργιος Β. Αναστασιάδης 9
Προσθήκη/Αποµάκρυνση Στοιχείου void enqueue(queueptr_t q, data_t d) { if (full(q)) printf( full queue ); else { /* προσθήκη στοιχείου */ q->queue[q->] = d; q-> = (q-> + ) % N; q->empty = ; void dequeue(queueptr_t q, data_t *d) { if (empty(q)) printf( empty queue ); else { /* αποµάκρυνση στοιχείου */ *d = q->queue[q->]; q-> = (q-> + ) % N; q->empty = (q-> == q->); N- N- Ανοιξη 5 Στέργιος Β. Αναστασιάδης
Υλοποίηση µε Μετρητή Για να µη µένει αχρησιµοποίητο ένα στοιχείο στη διάκριση κενής και γεµάτης ουράς εισάγουµε µετρητή στοιχείων count µε αρχική τιµή στη δοµή queue_t N- count == int empty(queueptr_t q) { return (q->count == ); N- int full(queueptr_t q) { return (q->count == N); count == N Ανοιξη 5 Στέργιος Β. Αναστασιάδης
Υλοποίηση Ουράς µε Λίστα typedef struct node { data_t data; struct node *next; node_t, *nodeptr_t; typedef struct { nodeptr_t, ; queue_t, *queueptr_t; queue_t queue; void create(queueptr_t q) { q-> = q-> = NULL; Ανοιξη 5 Στέργιος Β. Αναστασιάδης
Προσθήκη Κόµβου σε Ουρά int empty(queueptr_t q) { return (q-> == NULL); void enqueue(queueptr_t q, data_t d) { nodeptr_t newnode = (nodeptr_t) malloc(sizeof(node_t)); if (newnode == NULL) return; /* ουρά γεµάτη */ newnode->data = d; newnode->next = NULL; if (empty(q)) q-> = q-> = newnode; else {q->->next = newnode; q-> = newnode; newnode Ανοιξη 5 Στέργιος Β. Αναστασιάδης 3
Αποµάκρυνση Κόµβου από Ουρά void dequeue(queueptr_t q, data_t *d) { if (empty(q)) return; /* άδεια ουρά */ else { nodeptr_t oldnode = q->; *d = oldnode->data; q-> = oldnode->next; if (q-> == NULL) q-> = NULL; free(oldnode); oldnode Ανοιξη 5 Στέργιος Β. Αναστασιάδης 4
Εφαρµογή: Αποθήκευση Συµβολοσειράς ιαβάζουµε από αρχείο µια ακολουθία από χαρακτήρες Αποθηκεύουµε τµήµατα της ακολουθίας σε διαδοχικούς κόµβους ουράς ιατηρούµε τη διάταξη των χαρακτήρων σε δυναµική δοµή string chunk string chunk string chunk Ανοιξη 5 Στέργιος Β. Αναστασιάδης 5
Υλοποίηση Εφαρµογής typedef struct node { typedef struct { char data[chunk+]; nodeptr_t, ; struct node *next; queue_t, *queueptr_t; node_t, *nodeptr_t; do { if (fgets(buf, CHUNK+, stdin) /* + για \ */ break; /* enqueue chunk */ newnode = (nodeptr_t) malloc(sizeof(node_t)); strcpy(newnode->data, buf); newnode->next = NULL; if (q->) { q->->next = newnode; q-> = newnode; else /* άδεια ουρά */ q-> = q-> = newnode; while (buf[strlen(buf)-]!= \n ); Ανοιξη 5 Στέργιος Β. Αναστασιάδης 6