Μετάβαση στο περιεχόμενο

Αναζήτηση

Σειριακή και δυαδική αναζήτηση, και πόσα βήματα κάνει η καθεμία.

40 λεπτά

Θα μάθεις να

  1. Να περιγράφεις και να γράφεις σε Python τη σειριακή και τη δυαδική αναζήτηση.
  2. Να συμπληρώνεις πίνακα βημάτων για τη δυαδική αναζήτηση, με αρχή, τέλος και μέση.
  3. Να υπολογίζεις τον αριθμό συγκρίσεων στη χειρότερη περίπτωση για κάθε αλγόριθμο.
  4. Να εξηγείς γιατί η δυαδική αναζήτηση απαιτεί ταξινομημένη λίστα.

Ψάχνοντας μέσα σε δεδομένα

Κάθε φορά που γράφεις ένα όνομα στις επαφές του κινητού, που ένα eshop ελέγχει αν υπάρχει ένα προϊόν στην αποθήκη, που ο υπολογιστής της βιβλιοθήκης ψάχνει ένα βιβλίο, τρέχει ένας αλγόριθμος αναζήτησης: δίνεται μια λίστα και μια τιμή-στόχος, και ζητείται αν υπάρχει η τιμή στη λίστα και σε ποια θέση.

Δύο αλγόριθμοι λύνουν αυτό το πρόβλημα, πολύ διαφορετικοί στην ταχύτητα. Για να τους συγκρίνουμε, μετράμε συγκρίσεις: πόσα στοιχεία της λίστας εξετάζουμε, ελέγχοντας αν είναι ο στόχος.

Σειριακή αναζήτηση

Η πιο απλή ιδέα: ξεκινάς από την αρχή και ελέγχεις τα στοιχεία ένα ένα, μέχρι να βρεις τον στόχο ή να τελειώσει η λίστα. Λέγεται σειριακή ή γραμμική αναζήτηση (linear search).

def seiriaki(lista, stoxos):
    for i in range(len(lista)):
        if lista[i] == stoxos:
            return i
    return -1

arithmoi = [42, 7, 19, 88, 3, 56]
print(seiriaki(arithmoi, 88))
print(seiriaki(arithmoi, 5))
3
-1

Η συνάρτηση επιστρέφει τη θέση του στόχου. Αν δεν τον βρει, επιστρέφει -1, μια τιμή που δεν μπορεί να είναι θέση και άρα σημαίνει «δεν υπάρχει». Πρόσεξε ότι το return -1 είναι έξω από τον βρόχο: εκτελείται μόνο αν ο βρόχος τελειώσει χωρίς να βρει τίποτα.

ΣτόχοςΣτοιχεία που εξετάστηκανΣυγκρίσεις
424211: η καλύτερη περίπτωση
8842, 7, 19, 8844
5όλα, χωρίς επιτυχία66: η χειρότερη περίπτωση

Χειρότερη περίπτωση είναι όταν ο στόχος είναι τελευταίος ή δεν υπάρχει καθόλου. Τότε η σειριακή αναζήτηση κάνει τόσες συγκρίσεις όσα είναι τα στοιχεία: για λίστα με nn στοιχεία, nn συγκρίσεις.

Το μεγάλο πλεονέκτημά της: δουλεύει σε οποιαδήποτε λίστα, ταξινομημένη ή όχι.

Δυαδική αναζήτηση

Σκέψου πώς ψάχνεις μια λέξη σε ένα έντυπο λεξικό. Δεν ξεκινάς από τη σελίδα 11. Ανοίγεις κάπου στη μέση, βλέπεις ότι η λέξη σου είναι «πιο πριν», και πετάς όλο το δεύτερο μισό. Αυτό γίνεται μόνο επειδή το λεξικό είναι σε αλφαβητική σειρά.

Η δυαδική αναζήτηση (binary search) κάνει ακριβώς αυτό σε μια ταξινομημένη λίστα:

  1. Κοιτάζει το μεσαίο στοιχείο του τμήματος που απομένει.
  2. Αν είναι ο στόχος, τελείωσε.
  3. Αν είναι μικρότερο από τον στόχο, ο στόχος μόνο στο δεξί μισό μπορεί να είναι. Αν είναι μεγαλύτερο, μόνο στο αριστερό.
  4. Επαναλαμβάνει στο μισό που έμεινε, μέχρι να βρει τον στόχο ή να μη μείνει τίποτα.
def dyadiki(lista, stoxos):
    arxi = 0
    telos = len(lista) - 1
    while arxi <= telos:
        mesi = (arxi + telos) // 2
        if lista[mesi] == stoxos:
            return mesi
        elif lista[mesi] < stoxos:
            arxi = mesi + 1
        else:
            telos = mesi - 1
    return -1

taxin = [3, 8, 12, 17, 23, 31, 40, 52, 66]
print(dyadiki(taxin, 40))
print(dyadiki(taxin, 20))
6
-1

Οι μεταβλητές arxi και telos είναι οι δείκτες που οριοθετούν το κομμάτι της λίστας όπου μπορεί ακόμη να βρίσκεται ο στόχος. Η μέση υπολογίζεται με //, γιατί ο δείκτης πρέπει να είναι ακέραιος. Όταν το arxi ξεπεράσει το telos, το κομμάτι άδειασε και ο στόχος δεν υπάρχει.

Πίνακας βημάτων: δυαδική αναζήτηση του 20

Η λίστα είναι [3, 8, 12, 17, 23, 31, 40, 52, 66], με δείκτες 0 ως 8. Πριν πατήσεις, υπολόγισε τη νέα μέση.

ΒήμαΒήμαarxitelosmesilista[mesi]Απόφαση
Ζωντανή ενημέρωση
Στοιχεία nnΣειριακή, χειρότερηΔυαδική, χειρότερη
1010101044
10010010010077
10001000100010001010
1 000 0001\,000\,0001 000 0001\,000\,0002020

Σειριακή εναντίον δυαδικής

Μεγάλωσε τη λίστα και μετακίνησε τον στόχο. Κοίτα πόσο αλλάζει η μία μπάρα και πόσο η άλλη.

Η δυαδική θέλει ταξινομημένη λίστα. Η σειριακή όχι.

Συγκρίσεις για αυτή τη θέση

Σειριακή73

χειρότερη περίπτωση: 100

Δυαδική6

χειρότερη περίπτωση: 7

Άρα η επιλογή έχει κόστος: αν η λίστα αλλάζει συνέχεια και ψάχνεις σπάνια, ίσως δεν αξίζει να την ταξινομείς κάθε φορά. Αν ψάχνεις συχνά στα ίδια δεδομένα, η ταξινόμηση πληρώνεται μία φορά και κερδίζεται σε κάθε αναζήτηση. Γι' αυτό το επόμενο μάθημα είναι η ταξινόμηση.

Λυμένα παραδείγματα

Παράδειγμα 1

Ψάξε με δυαδική αναζήτηση το 40 στη λίστα [3, 8, 12, 17, 23, 31, 40, 52, 66]. Πόσες συγκρίσεις χρειάζονται;

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Παράδειγμα 2

Ένας κατάλογος έχει 500 ταξινομημένα ονόματα. Πόσες συγκρίσεις χρειάζεται στη χειρότερη περίπτωση η σειριακή και πόσες η δυαδική αναζήτηση;

Δοκίμασέ το πρώτα. Μετά δες τη λύση.

Ασκήσεις

Πρώτα ερωτήσεις με επιλογές: διαλέγεις, πατάς «Έλεγξε» και μαθαίνεις αμέσως αν το βρήκες και γιατί. Στο τέλος, λίγες ασκήσεις χωρίς επιλογές — εκεί κρύβεται μόνο η απάντηση.

Πολλαπλή επιλογήΆσκηση 1 από 14
Πόσες συγκρίσεις κάνει η σειριακή αναζήτηση στη χειρότερη περίπτωση, σε λίστα με 50 στοιχεία;

Τα κατάφερες;

  • Να περιγράφεις και να γράφεις σε Python τη σειριακή και τη δυαδική αναζήτηση.
  • Να συμπληρώνεις πίνακα βημάτων για τη δυαδική αναζήτηση, με αρχή, τέλος και μέση.
  • Να υπολογίζεις τον αριθμό συγκρίσεων στη χειρότερη περίπτωση για κάθε αλγόριθμο.
  • Να εξηγείς γιατί η δυαδική αναζήτηση απαιτεί ταξινομημένη λίστα.

Λύσε τις ασκήσεις πιο πάνω και θα δεις εδώ πού στέκεσαι.