Δυαδική αναζήτηση: Διαφορά μεταξύ των αναθεωρήσεων
Περιεχόμενο που διαγράφηκε Περιεχόμενο που προστέθηκε
Χωρίς σύνοψη επεξεργασίας |
Vevek (συζήτηση | συνεισφορές) Χωρίς σύνοψη επεξεργασίας |
||
Γραμμή 1:
{{Πηγές|27|05|2011}}<br>
'''Δυαδική αναζήτηση''' ονομάζεται ένας [[αναδρομή|αναδρομικός]] [[αλγόριθμος]] αναζήτησης ενός στοιχείου (το λεγόμενο ''στοιχείο-κλειδί'') σε έναν ταξινομημένο μονοδιάστατο πίνακα. Εν γένει, η αναζήτηση σε έναν μη ταξινομημένο πίνακα γίνεται σε χρόνο γραμμικό ως προς το μέγεθος της εισόδου, συγκρίνοντας ένα προς ένα τα στοιχεία της εισόδου με το κλειδί. Όμως, η δυαδική αναζήτηση στηρίζεται στο γεγονός ότι ο πίνακας είναι ταξινομημένος, μειώνοντας έτσι σημαντικά τον αριθμό των συγκρίσεων που απαιτούνται.
Εναλλακτικά μπορεί να χρησιμοποιηθεί κάποια άλλη [[δομή δεδομένων]], αλλά είναι απαραίτητο αυτή να υποστηρίζει την τυχαία προσπέλαση σε σταθερό χρόνο. Για παράδειγμα, η δυαδική αναζήτηση δεν μπορεί να εφαρμοστεί σε μια δομή δεδομένων όπως η [[Λίστα (αφηρημένος τύπος δεδομένων)|λίστα]].
==Περιγραφή==
Ο αλγόριθμος δέχεται ως είσοδο έναν ταξινομημένο μονοδιάστατο πίνακα (διάνυσμα) και μια τιμή που ονομάζεται ''κλειδί''. Επιστρέφει την θέση του κλειδιού στο διάνυσμα ή μια ειδική ένδειξη για να ενημερώσει ότι το κλειδί δεν υπάρχει στο διάνυσμα, αν αυτή είναι η περίπτωση. Το διάνυσμα μπορεί να είναι ταξινομημένο είτε σε αύξουσα σειρά είτε σε φθίνουσα, αλλά και στις δύο περιπτώσεις ο αλγόριθμος μπορεί να λειτουργήσεις σωστά (με τις κατάλληλες τροποποιήσεις) και στον ίδιο χρόνο. Λόγω της ισοδυναμίας αυτής, μπορούμε χωρίς βλάβη της γενικότητας να θεωρήσουμε ότι το διάνυσμα είναι ταξινομημένο κατά αύξουσα σειρά.
Επειδή το διάνυσμα είναι ταξινομημένο, η τιμή του στοιχείου στη θέση i του διανύσματος θα είναι μικρότερη από όλα τα στοιχεία δεξιά και μεγαλύτερη από όλα τα στοιχεία αριστερά (στην περίπτωση που δεν έχουμε επαναλαμβανόμενες τιμές). Έτσι, αν σε μια σύγκριση, το κλειδί είναι μεγαλύτερο από το στοιχείο στη θέση i, δεν έχει νόημα να κάνουμε συγκρίσεις με τα στοιχεία που βρίσκονται σε θέση j<i (δηλαδή, αριστερά από τη θέση i). Αυτήν ακριβώς την ιδιότητα εκμεταλλεύεται η δυαδική αναζήτηση, ώστε να μειώσει κατά το δυνατό τις συγκρίσεις που κάνει.
===Ακραίες περιπτώσεις===▼
Αρχικά, το εύρος των θέσεων στις οποίες μπορεί να βρίσκεται το στοιχείο με τιμή ίση με το κλειδί είναι το μεγαλύτερο δυνατό. Δηλαδή, αρχικά ο αλγόριθμος θεωρεί ότι το κλειδί μπορεί να βρίσκεται οπουδήποτε μέσα στο διάνυσμα.
# Ξεκινά συγκρίνοντας το κλειδί με την τιμή του στοιχείου που βρίσκεται στο μέσο του διανύσματος.
# Αν είναι ίσα, τότε ο αλγόριθμος τερματίζει επιστρέφοντας τη θέση αυτή.
# Αν το κλειδί είναι μεγαλύτερο, τότε μειώνει το εύρος στο δεξί-μισό τμήμα του προηγούμενου τμήματος που εξέταζε και επαναλαμβάνει το πρώτο βήμα όχι για όλο το διάνυσμα, αλλά μόνο για το τμήμα του διανύσματος που επέλεξε.
# Αν το κλειδί είναι μικρότερο, τότε μειώνει το εύρος στο αριστερό-μισό τμήμα του προηγούμενου τμήματος που εξέταζε και επαναλαμβάνει το πρώτο βήμα όχι για όλο το διάνυσμα, αλλά μόνο για το τμήμα του διανύσματος που επέλεξε.
Μετά από έναν πεπερασμένο αριθμό βημάτων, ο αλγόριθμος είτε θα βρει τη ζητούμενη θέση, είτε θα μειώσει το εύρος της αναζήτησης στο μηδέν, που σημαίνει ότι το κλειδί δεν βρέθηκε στο διάνυσμα, και θα επιστρέψει την αντίστοιχη ένδειξη.
▲===Ακραίες περιπτώσεις===
Αν υπάρχει περίπτωση το στοιχείο-κλειδί να υπάρχει περισσότερες φορές και χρειάζεται να επιστραφούν όλες οι θέσεις, τότε ο αλγόριθμος χρειάζεται επιπλέον τροποποίηση.
==Χρονική πολυπλοκότητα==
Η χρονική πολυπλοκότητα του αλγόριθμου είναι λογαριθμική ως προς το μέγεθος της εισόδου. Έστω ότι το διάνυσμα της εισόδου είναι μεγέθους n (έχει n στοιχεία) και έστω T(n) ο χρόνος που χρειάζεται στη χειρότερη περίπτωση (όπου το κλειδί δεν υπάρχει στο διάνυσμα) για να βρει τη θέση του κλειδιού, ψάχοντας σε όλο το διάνυσμα. Και έστω ότι η σύγκριση παίρνει σταθερό χρόνο c. Τότε,
:<math>T(n) =
\begin{cases}
c & \mbox{if } n=0\\
T \left( \lfloor \frac{n}{2} \rfloor \right)+c &\mbox{if } n>0
\end{cases}
</math>
Η λύση της αναδρομικής αυτής εξίσωσης είναι
:<math>T(n) =c \cdot \log n +c = O(\log n)</math>
== Δείτε επίσης ==
* [[Γραμμική αναζήτηση]]
{{Αλγόριθμος-επέκταση}}
|