pontifikas wrote: |
mikem4600 wrote: | Απ' όσο μπόρεσα να
καταλάβω από το documentation της MSDN τα hashtables κάνουν chaining,
άρα η προσπέλαση σε αυτά είναι O(1) (ή τέλος πάντων O(1+load_factor)).
|
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!![Surprise [:O]](/cs/emoticons/emotion-3.gif) ΜΠορείς να μου το εξηγήσεις αυτό!!! Το διάβασα και στο MSDN. Πώς είναι δυνατό? Τί είναι το chaining!!!
Πάντως
Insertions ¨εχω μόνο στην αρχή και deletions μόνο στο τέλος.Μόνο
Αναζητήσεις έχω και μεταβολές(το οποίο όπως λέει πάλι Ο(1) είναι).
|
|
To chaining είναι ένας από τους τρόπους αποθήκευσης στοιχείων σε hashtable (ένας άλλος είναι το open addressing).
Χοντρικά, τα hashtables χρησιμοποιούν μια συνάρτηση που λέγεται hash function. Αυτή παίρνει ως είσοδο ένα κλειδί (π.χ. ένα string) και το αντιστοιχεί με έναν ακέραιο στο διάστημα [1-n] (ιδανικά, με ισοπίθανο τρόπο). Τα hashtables χρησιμοποιούν ένα πίνακα μεγέθους n για την αποθήκευση των στοιχείων. Κάθε στοιχείο αποθηκεύεται στη θέση του πίνακα που αντιστοιχεί στο hash code του.
Η συνάρτηση αυτή υπολογίζεται σε O(1) και έχει την ιδιότητα να αντιστοιχεί πάντα το ίδιο κλειδί στον ίδιο ακέραιο. Αυτό όμως δεν σημαίνει, όπως παρατήρησες, ότι κάθε (διαφορετικό) κλειδί αντιστοιχεί σε διαφορετικό ακέραιο. Σε περίπτωση που υπάρχει conflict, δηλαδή δύο διαφορετικά κλειδιά πρέπει να αποθηκευτούν στην ίδια θέση του πίνακα (επειδή η hash function επέστρεψε τον ίδιο ακέραιο), τότε στο chaining χρησιμοποιείται μία λίστα (για τη συγκεκριμένη θέση του πίνακα), που λέγεται bucket. Οπότε δεν χρειάζεται (και δεν γίνεται) να παράγει η hash function μοναδικά αποτελέσματα για κάθε κλειδί (αφού σε αυτή την περίπτωση δεν θα χρειαζόμασταν τη hash function - και το κλειδί μοναδικό είναι).
Άρα ένα hashtable σε αυτή την περίπτωση είναι ουστιαστικά ένας πίνακας που κάθε κελί του είναι μια λίστα. Για να βρω ένα στοιχείο, υπολογίζω το hashcode του (με τη hash function, δηλ. σε O(1)) και αυτό μου υποδυκνείει τη θέση του πίνακα όπου βρίσκεται αποθηκευμένο το στοιχείο αυτό (και αυτό σε O(1) μπορώ να το προσπελάσω). Ιδανικά (δηλ. αν δεν υπάρχουν conflicts) έχω τελειώσει. Αν όμως έχουν συμβεί conflicts, στη θέση αυτή θα υπάρχουν πολλά στοιχεία (στη λίστα) και θα πρέπει να την ψάξω σειριακά (αφού ούτε ταξινομημένη είναι, ούτε τπτ). Αυτό θέλει χρόνο ανάλογο του βαθμού χρησιμοποίησης του hashtable (που ισούται με m/n όπου m τα στοιχεία που κρατάει το hashtable), δηλ. O(m/n). Συνολικά: O(1)+O(m/n)=O(1+m/n) (αυτό διότι δεν ξέρουμε αν 1 > m/n ή 1 < m/n).
Μερικά links:
http://www.sparknotes.com/cs/searching/hashtables/section1.html
http://en.wikipedia.org/wiki/Hash_table#Chaining
http://www.gamedev.net/reference/articles/article2066.asp