Ουρά (δομή δεδομένων)

Η ουρά (queue) στην πληροφορική είναι μια δομή δεδομένων με τη μορφή παρατεταμένης συλλογής. Η βασική λειτουργικότητα είναι η εισαγωγή στοιχείων στην πίσω θέση και η εξαγωγή-διαγραφή στοιχείων από την μπροστινή θέση. Με αυτόν τον τρόπο, η ουρά είναι μια FIFO (First-In-First-Out, Πρώτο-Μέσα-Πρώτο-Έξω) δομή δεδομένων. Σε μια FIFO δομή δεδομένων, το πρώτο στοιχείο που εισάγεται στην ουρά θα είναι το πρώτο που θα αφαιρεθεί-εξυπηρετηθεί. Οι ουρές χρησιμοποιούνται στον προγραμματισμό υπολογιστών ως δομές δεδομένων. Είναι ο αφηρημένος τύπος δεδομένων μιας ουράς αναμονής στην καθημερινή ζωή (π.χ. μια ουρά εξυπηρέτησης πελατών σε ένα ταμείο). Στις αντικειμενοστρεφείς γλώσσες προγραμματισμού υλοποιούνται ως κλάσεις-αντικείμενα. Συνήθεις χρήσεις των ουρών είναι σε κυκλικές προσωρινές μνήμες και στις διασυνδεδεμένες λίστες. Ένα άλλο παράδειγμα χρήσης των ουρών είναι στην λειτουργία της προσωρινής μνήμης (buffer).

 Η ιδιότητα μέσω της οποίας καθορίζεται μια δομή δεδομένων ως ουρά είναι το γεγονός ότι αυτή επιτρέπει πρόσβαση μόνο στην αρχή και στο τέλος της ουράς. Επιπροσθέτως, τα στοιχεία μπορούν να διαγραφούν μόνο από μπροστά και μπορούν να εισαχθούν μόνο πίσω. Έτσι, μια παρομοίωση που ταιριάζει, και συχνά χρησιμοποιείται για να δώσει μια αναπαράσταση της ουράς, είναι οι ουρές των ταμείων πληρωμής. Άλλα παραδείγματα καθημερινών ουρών είναι άνθρωποι που ανεβαίνουν από κυλιόμενες σκάλες, κομμάτια μηχανών τοποθετημένα σε αλυσίδα συναρμολόγησης ή αυτοκίνητα στη σειρά σε ένα βενζινάδικο. Σε κάθε περίπτωση, το πρόσωπο ή το αντικείμενο στην αρχή της ουράς είναι το πρώτο που θα φύγει, ενώ στο τέλος της ουράς είναι αυτό που θα φύγει τελευταίο. Κάθε φορά που το πρόσωπο ή το αντικείμενο τελειώνει την δουλειά του, εκείνο φεύγει από την ουρά από μπροστά. Αυτό αναπαριστά τη διαδικασία "dequeue" (εξαγωγή). Κάθε φορά που ένα πρόσωπο ή ένα αντικείμενο μπαίνουν στην ουρά αναμονής, εισέρχονται από το τέλος της ουράς και αυτό αναπαριστά τη διαδικασία "enqueue" (εισαγωγή). Η συνάρτηση "size" επιστρέφει το μήκος της γραμμής και η συνάρτηση "empty" θα επέστρεφε true μόνο αν δεν υπήρχε κανείς στη γραμμή. Θεωρητικά, ένα χαρακτηριστικό της ουράς είναι ότι δεν έχει συγκεκριμένο μέγεθος. Ασχέτως από το πόσα στοιχεία περιέχονται ήδη, ένα νέο στοιχείο μπορεί πάντα να εισαχθεί. Στην περίπτωση που η ουρά είναι άδεια δεν μπορεί να γίνει εξαγωγή "dequeue" στοιχείου πριν εισαχθεί κάποιο νέο. Μια πρακτική υλοποίηση ουράς γίνεται συνήθως με δείκτες στην οποία το όριο μεγέθους περιορίζεται από την διαθέσιμη μνήμη που έχει ο υπολογιστής. Ένας άλλος τρόπος υλοποίησης της ουράς είναι σε μια δομή δεδομένων σε σταθερό μέγεθος εκχωρημένης μνήμης. Ο όρος υπερχείλιση μιας ουράς συμβαίνει κατά την προσπάθεια να εισαχθεί ένα στοιχείο σε μια γεμάτη ουρά, ενώ η υποχείλιση συμβαίνει κατά την προσπάθεια διαγραφής-εξαγωγής ενός στοιχείου από μια άδεια ουρά. Το παρακάτω παράδειγμα προγραμματισμού στην γλώσσα C χρησιμοποιεί μια δυναμική λίστα και δυναμική εκχώρηση μνήμης: Ουρές δεδομένων μπορούν να δημιουργηθούν με την χρήση του κοντέινερ queue της πρότυπης βιβλιοθήκης C++. Στο παρακάτω παράδειγμα στην C++ έχουμε την υλοποίηση μιας κυκλικής ουράς χρησιμοποιώντας ένα πίνακα σταθερού μεγέθους και μεταβλητές οι οποίες είναι ορατές παντού (global variables). Δεν χρειάζεται δυναμική εκχώρηση μνήμης η οποία θα επηρέαζε την απόδοση του προγράμματος. Αλλάζοντας την θέση της κεφαλής και της ουράς, δεν χρειάζεται να αλλάξουμε τη θέση των υπόλοιπων μελών μέσα στην μνήμη. Είναι το φυσικό παράδειγμα μιας ουράς ανθρώπων στην οποία ο πρώτος μετακινείται στο τέλος της ουράς χωρίς να χρειάζεται κανείς άλλος στην ουρά να αλλάξει θέση. Η έξοδος του παραπάνω προγράμματος είναι της μορφής: Βασισμένο σ' ένα παράδειγμα από το βιβλίο R.S. Algorithms (Αλγόριθμοι). Στην γλώσσα προγραμματισμού Python ένα αντικείμενο list μπορεί να χρησιμοποιηθεί ως ουρά δεδομένων. Η χρήση του list ως ουρά είναι επικριθεί λόγω της πολυπλοκότητας στην λειτουργίας εξαγωγής στοιχείων μέσω της pop λειτουργίας. Το αντικείμενο deque είναι διαθέσιμο και θεωρείται πιο βολικό για λειτουργίες εξαγωγής στοιχείων από οποιαδήποτε πλευρά της λίστας με σταθερή πολυπλοκότητα. Ο παρακάτω κώδικας δείχνει μια απλή υλοποίηση ουράς στην Python: Ντόναλντ Κνουθ. The Art of Computer Programming, Volume 1: Fundamental Algorithms, Third Edition. Addison-Wesley, 1997. ISBN 0-201-89683-4. Section 2.2.1: Stacks, Queues, and Deques, pp. 238–243. Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algorithms, Second Edition. MIT Press and McGraw-Hill, 2001. ISBN 0-262-03293-7. Section 10.1: Stacks and queues, pp.200–204. William Ford, William Topp. Data Structures with C++ and STL, Second Edition. Prentice Hall, 2002. ISBN 0-13-085850-1. Chapter 8: Queues and Priority Queues, pp.386–390. Adam Drozdek. Data Structures and Algorithms in C++, Third Edition. Thomson Course Technology, 2005. ISBN 0-534-49182-0. Chapter 4: Stacks and Queues, pp.137–169.