Ένας πίνακας κατακερματισμού αποθηκεύει ζεύγη κλειδιού-τιμής εφαρμόζοντας κατακερματισμό σε κάθε κλειδί ώστε να το αντιστοιχίσει σε έναν δείκτη πίνακα. Αυτό επιτρέπει στον πίνακα να πηγαίνει κοντά στη σωστή θέση αντί να ελέγχει ένα-ένα όλα τα αποθηκευμένα στοιχεία.
Γι’ αυτό οι πίνακες κατακερματισμού έχουν συχνά μέση πολυπλοκότητα κοντά στο για αναζήτηση, εισαγωγή και διαγραφή. Η προϋπόθεση όμως έχει σημασία: η συνάρτηση κατακερματισμού πρέπει να κατανέμει τα κλειδιά αρκετά καλά και ο πίνακας πρέπει να έχει κανόνα για τις συγκρούσεις.
Τι κάνει ένας πίνακας κατακερματισμού
Ένας πίνακας κατακερματισμού αποθηκεύει ζεύγη κλειδιού-τιμής όπως "name" -> "Ada" ή 42 -> "blue". Έχει δύο βασικά μέρη:
- έναν πίνακα από θέσεις ή κάδους
- μια συνάρτηση κατακερματισμού που αντιστοιχίζει κάθε κλειδί σε μία από αυτές τις θέσεις
Αν ο πίνακας έχει θέσεις, μπορείς να σκεφτείς τη συνάρτηση κατακερματισμού ως κάτι που παράγει έναν δείκτη από έως .
Για ένα μικρό παράδειγμα με ακεραίους, ο κανόνας μπορεί να είναι
Τότε το κλειδί πηγαίνει στη θέση , επειδή .
Οι πραγματικές συναρτήσεις κατακερματισμού σχεδιάζονται πιο προσεκτικά, ειδικά για συμβολοσειρές και μεγαλύτερα σύνολα δεδομένων. Όμως η βασική ιδέα μένει ίδια: υπολόγισε γρήγορα έναν δείκτη και μετά έλεγξε το στοιχείο που είναι αποθηκευμένο εκεί.
Γιατί οι συγκρούσεις κατακερματισμού είναι αναπόφευκτες
Σύγκρουση συμβαίνει όταν δύο διαφορετικά κλειδιά αντιστοιχίζονται στην ίδια θέση.
Αυτό είναι φυσιολογικό, επειδή ο πίνακας συνήθως έχει λιγότερες θέσεις από τον αριθμό των πιθανών κλειδιών. Με
τα κλειδιά , και αντιστοιχίζονται όλα στη θέση . Άρα, παρόλο που η συνάρτηση λειτουργεί ακριβώς όπως ορίζεται, ο πίνακας εξακολουθεί να έχει μια σύγκρουση που πρέπει να επιλύσει.
Άρα ένας πίνακας κατακερματισμού δεν υπόσχεται μοναδική θέση για κάθε κλειδί. Υπόσχεται έναν γρήγορο τρόπο να περιορίσει την αναζήτηση, αρκεί οι συγκρούσεις να αντιμετωπίζονται σωστά.
Παράδειγμα βήμα προς βήμα: ένας πίνακας, μία σύγκρουση
Έστω ότι ένας πίνακας έχει θέσεις και χρησιμοποιεί
Εισήγαγε τα κλειδιά , και .
Πρώτα, το πηγαίνει στη θέση , επειδή .
Στη συνέχεια, το κατακερματίζεται επίσης στη θέση , οπότε προκύπτει σύγκρουση.
Έπειτα, το πηγαίνει στη θέση , άρα αυτή η εισαγωγή δεν συγκρούεται.
Το χρήσιμο μοτίβο είναι πάντα το ίδιο:
- Κάνε hash το κλειδί.
- Πήγαινε στην προτεινόμενη θέση.
- Αν υπάρχει ήδη εκεί διαφορετικό κλειδί, εφάρμοσε τον κανόνα επίλυσης σύγκρουσης.
Μόλις αυτό το μοτίβο γίνει σαφές, οι δύο βασικές στρατηγικές επίλυσης συγκρούσεων είναι πιο εύκολο να κατανοηθούν.
Chaining έναντι open addressing
Το chaining κρατά έναν κάδο σε κάθε θέση
Στο chaining, κάθε θέση αποθηκεύει μια μικρή συλλογή από εγγραφές αντί για μία μόνο.
Αν τα και κατακερματίζονται και τα δύο στη θέση , ο κάδος μπορεί να αποθηκεύει
Για να βρει το κλειδί , ο πίνακας πηγαίνει στον κάδο και συγκρίνει μόνο τις εγγραφές αυτού του κάδου.
Το chaining είναι εννοιολογικά απλό και η διαγραφή είναι συνήθως ευκολότερη από ό,τι στο open addressing. Το μειονέκτημα είναι ότι οι μεγάλοι κάδοι κάνουν τις πράξεις πιο αργές.
Το open addressing μένει μέσα στον πίνακα
Στο open addressing, κάθε θέση του πίνακα κρατά το πολύ μία εγγραφή. Αν η αρχική θέση είναι γεμάτη, ο πίνακας δοκιμάζει άλλες θέσεις σύμφωνα με έναν σταθερό κανόνα.
Ένας συνηθισμένος κανόνας είναι η γραμμική διερεύνηση: αν η θέση είναι κατειλημμένη, δοκίμασε τη , μετά τη , μετά τη , και συνέχισε κυκλικά αν χρειαστεί.
Αυτό αποφεύγει ξεχωριστές λίστες κάδων, αλλά οι γειτονικές γεμάτες θέσεις μπορούν να σχηματίσουν συσσωματώματα. Μια ακόμη λεπτομέρεια είναι ότι η αναζήτηση και η διαγραφή πρέπει να ακολουθούν τον ίδιο κανόνα διερεύνησης που χρησιμοποιήθηκε κατά την εισαγωγή.
Πότε ο ισχυρισμός είναι δίκαιος
Οι πίνακες κατακερματισμού συχνά περιγράφονται ως δομές με αναζήτηση, εισαγωγή και διαγραφή κατά μέσο όρο. Αυτή η δήλωση για τη μέση περίπτωση εξαρτάται από προϋποθέσεις:
- η συνάρτηση κατακερματισμού κατανέμει τα κλειδιά αρκετά καλά
- ο συντελεστής φόρτωσης παραμένει υπό έλεγχο
- η στρατηγική επίλυσης συγκρούσεων υλοποιείται σωστά
Ο συντελεστής φόρτωσης είναι ο λόγος
Αν ο πίνακας γεμίσει υπερβολικά, οι συγκρούσεις γίνονται συχνότερες και η απόδοση χειροτερεύει. Γι’ αυτό πολλές υλοποιήσεις αλλάζουν το μέγεθος του πίνακα καθώς γεμίζει.
Η απόδοση στη χειρότερη περίπτωση μπορεί παρ’ όλα αυτά να υποβαθμιστεί προς το αν πάρα πολλά κλειδιά συσσωρευτούν στην ίδια περιοχή.
Συνηθισμένα λάθη με τους πίνακες κατακερματισμού
Να υποθέτεις ότι οι συγκρούσεις σημαίνουν πως απέτυχε η συνάρτηση κατακερματισμού
Δεν σημαίνει αυτό. Οι συγκρούσεις είναι αναμενόμενες. Το πραγματικό ερώτημα είναι αν ο πίνακας τις χειρίζεται αποδοτικά.
Να θεωρείς το ως άνευ όρων
Το είναι συνήθως δήλωση για τη μέση περίπτωση, όχι υπόσχεση για κάθε είσοδο και κάθε χρονική στιγμή.
Να συγχέεις το hashing εδώ με την κρυπτογράφηση
Μια συνάρτηση κατακερματισμού στο πλαίσιο των βασικών δομών δεδομένων αφορά κυρίως τη γρήγορη δεικτοδότηση, όχι τη μυστικότητα. Αυτοί είναι διαφορετικοί στόχοι.
Να ξεχνάς να συγκρίνεις το πραγματικό κλειδί
Δύο κλειδιά μπορούν να έχουν το ίδιο αποτέλεσμα κατακερματισμού. Αφού φτάσει στον σωστό κάδο ή στη σωστή θέση διερεύνησης, ο πίνακας πρέπει πάλι να ελέγξει αν το κλειδί όντως ταιριάζει.
Πού χρησιμοποιούνται οι πίνακες κατακερματισμού
Οι πίνακες κατακερματισμού χρησιμοποιούνται όπου έχει σημασία η γρήγορη αναζήτηση με βάση κλειδί. Συνηθισμένα παραδείγματα είναι τα λεξικά, οι πίνακες συμβόλων, οι cache, η δεικτοδότηση και η καταμέτρηση συχνοτήτων σε δεδομένα.
Είναι πολύ κατάλληλοι όταν η ακριβής αναζήτηση με βάση κλειδί είναι πιο σημαντική από το να διατηρούνται τα στοιχεία σε ταξινομημένη σειρά. Αν χρειάζεσαι διάσχιση με σειρά, ερωτήματα εύρους ή κοντινότερες τιμές, ίσως είναι προτιμότερη μια διαφορετική δομή.
Δοκίμασε ένα παρόμοιο παράδειγμα σύγκρουσης
Πάρε έναν μικρό πίνακα με θέσεις και χρησιμοποίησε . Εισήγαγε μερικά κλειδιά όπως , , και . Έπειτα επίλυσε τις συγκρούσεις μία φορά με chaining και μία φορά με γραμμική διερεύνηση.
Αυτή η μία άσκηση κάνει τη βασική ιδέα πολύ γρήγορα συγκεκριμένη: οι συγκρούσεις είναι αναπόφευκτες και ο κανόνας επίλυσής τους αλλάζει τη συμπεριφορά του πίνακα. Αν θέλεις ένα χρήσιμο επόμενο βήμα, δοκίμασε τη δική σου εκδοχή με διαφορετικό μέγεθος πίνακα και δες πώς αλλάζουν οι συγκρούσεις.
Χρειάζεσαι βοήθεια με μια άσκηση;
Ανέβασε την ερώτησή σου και πάρε επαληθευμένη λύση βήμα-βήμα σε δευτερόλεπτα.
Άνοιξε το GPAI Solver →