Γιατί είναι std :: map υλοποιείται ως ένα κόκκινο-μαύρο δέντρο;

ψήφοι
130

Γιατί είναι std :: map υλοποιείται ως ένα κόκκινο-μαύρο δέντρο ;

Υπάρχουν αρκετές ισορροπημένη δυαδικό δέντρο αναζήτησης (BSTs) εκεί έξω. Τι ήταν το σχεδιασμό συμβιβασμούς στην επιλογή ένα κόκκινο-μαύρο δέντρο;

Δημοσιεύθηκε 13/03/2011 στις 09:33
πηγή χρήστη
Σε άλλες γλώσσες...                            


6 απαντήσεις

ψήφοι
86

Πιθανώς οι δύο πιο κοινές αλγόριθμοι αυτο εξισορρόπηση δέντρο είναι Κόκκινο-Μαύρο δέντρα και AVL δέντρα . Για να εξισορροπήσει το δέντρο μετά από μια εισαγωγή / ενημέρωση και οι δύο αλγόριθμοι χρησιμοποιούν την έννοια των περιστροφών, όπου οι κόμβοι του δέντρου περιστρέφεται για να εκτελέσει την εκ νέου εξισορρόπηση.

Ενώ σε δύο αλγόριθμοι το ένθετο / διαγραφή λειτουργίες είναι O (log n), στην περίπτωση της Red-Μαύρο περιστροφή δέντρο επανεξισορρόπησης είναι ένα O (1) λειτουργία ενώ με AVL αυτό είναι μια O (log n) λειτουργία, καθιστώντας το Κόκκινο-Μαύρο δέντρο πιο αποτελεσματική σε αυτή την πτυχή του σταδίου εκ νέου εξισορρόπηση και ένας από τους πιθανούς λόγους που είναι πιο συχνά χρησιμοποιείται.

Τα κόκκινα-μαύρα δέντρα που χρησιμοποιούνται στις περισσότερες βιβλιοθήκες συλλογή, συμπεριλαμβανομένων των προσφορών από την Ιάβα και Microsoft .NET Framework.

Απαντήθηκε 13/03/2011 στις 09:47
πηγή χρήστη

ψήφοι
2

Είναι ακριβώς η επιλογή της εφαρμογής σας - θα μπορούσαν να εφαρμοστούν και κάθε ισορροπημένο δέντρο. Οι διάφορες επιλογές είναι όλα συγκρίσιμα με μικρές διαφορές. Επομένως, κάθε είναι τόσο καλή όσο οποιαδήποτε.

Απαντήθηκε 13/03/2011 στις 09:48
πηγή χρήστη

ψήφοι
22

AVL δέντρα έχουν μέγιστο ύψος 1.44logn, ενώ RB δέντρα έχουν ένα μέγιστο των 2logn. Εισαγωγή ενός στοιχείου σε ένα AVL μπορεί να συνεπάγεται μία νέα εξισορρόπηση σε ένα σημείο στο δέντρο. Η επανεξισορρόπηση ολοκληρώνει την εισαγωγή. Μετά την εισαγωγή ενός νέου φύλλου, την ενημέρωση των προγόνων του εν λόγω φύλλου πρέπει να γίνει μέχρι τη ρίζα, ή μέχρι ένα σημείο όπου οι δύο υποδένδρων είναι ίσης βάθος. Η πιθανότητα του να πρέπει να ενημερώσει k κόμβους είναι το 1/3 ^ k. Εξισορρόπηση είναι Ο (1). Αφαίρεση ενός στοιχείου μπορεί να συνεπάγεται περισσότερες από μία εξισορρόπηση (μέχρι το ήμισυ του βάθους του δέντρου).

RB-δέντρα είναι Β-δέντρα της τάξης 4 εκπροσωπήθηκαν ως δυαδικά δέντρα αναζήτησης. Ένα 4-κόμβος στα αποτελέσματα Β-δέντρο σε δύο επίπεδα στην ισοδύναμη BST. Στη χειρότερη περίπτωση, όλοι οι κόμβοι του δέντρου είναι 2-κόμβους, με μία μόνο αλυσίδα 3-κόμβων προς τα κάτω σε ένα φύλλο. Αυτό φύλλο θα είναι σε απόσταση 2logn από τη ρίζα.

Κατεβαίνοντας από τη ρίζα προς το σημείο εισαγωγής, πρέπει κανείς να αλλάξει 4-κόμβους σε 2-κόμβους, για να βεβαιωθείτε ότι οποιαδήποτε παρεμβολή δεν θα κορέσει ένα φύλλο. Επιστρέφοντας από την εισαγωγή, όλοι αυτοί οι κόμβοι πρέπει να αναλυθούν για να βεβαιωθείτε ότι σωστά αντιπροσωπεύουν 4-κόμβους. Αυτό μπορεί να γίνει και κατεβαίνοντας στο δέντρο. Το συνολικό κόστος θα είναι το ίδιο. Δεν υπάρχει δωρεάν γεύμα! Αφαίρεση ενός στοιχείου από το δέντρο είναι της ίδιας τάξης.

Όλα αυτά τα δέντρα απαιτούν κόμβους μεταφέρουν πληροφορίες σχετικά με το ύψος, το βάρος, το χρώμα, κλπ Μόνο δέντρα Splay είναι απαλλαγμένες από τέτοιες περισσότερες πληροφορίες. Αλλά οι περισσότεροι άνθρωποι φοβούνται δέντρα Splay, λόγω της ramdomness της δομής τους!

Τέλος, τα δέντρα μπορούν επίσης να μεταφέρουν πληροφορίες βάρους στους κόμβους, επιτρέποντας βάρος εξισορρόπησης. μπορούν να εφαρμοστούν διάφορα σχήματα. Κάποιος πρέπει να αποκαταστήσει την ισορροπία όταν ένα υποδένδρο περιέχει περισσότερες από 3 φορές τον αριθμό των στοιχείων του άλλου υποδένδρο. Εξισορρόπηση και πάλι γίνεται είτε throuh μια μονή ή διπλή περιστροφή. Αυτό σημαίνει χειρότερη περίπτωση 2.4logn. Κάποιος μπορεί να ξεφύγει με 2 φορές αντί για 3, μια πολύ καλύτερη αναλογία, αλλά αυτό μπορεί να σημαίνει αφήνοντας λίγο λιγότερο Thant 1% των υποδένδρων ισορροπημένη εδώ και εκεί. Πονηρός!

Ποιο είδος του δέντρου είναι το καλύτερο; AVL σίγουρα. Είναι η πιο απλή στον κώδικα, και να έχουν χειρότερη ύψος τους πλησιέστερα προς logn. Για ένα δέντρο των 1000000 στοιχείων, ένα AVL θα είναι στο μεγαλύτερο μέρος του ύψους 29, ένα RB 40, και ένα βάρος βάση 36 ή 50 ανάλογα με την αναλογία.

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

Απαντήθηκε 16/07/2011 στις 02:52
πηγή χρήστη

ψήφοι
36

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

std::map χρησιμοποιεί κόκκινο-μαύρο δέντρο και παίρνει ένα λογικό συμβιβασμό ανάμεσα στην ταχύτητα του κόμβου εισαγωγή / διαγραφή και αναζήτηση.

Απαντήθηκε 26/05/2012 στις 19:32
πηγή χρήστη

ψήφοι
2

Ενημέρωση 14/6/2017: webbertiger επεξεργαστείτε απάντησή του μετά σχολίασα. Θα ήθελα να επισημάνω ότι η απάντησή της είναι πλέον πολύ καλύτερα στα μάτια μου. Αλλά συνέχισα την απάντησή μου ακριβώς όπως πρόσθετες πληροφορίες ...

Λόγω του γεγονότος ότι πιστεύω ότι πρώτη απάντηση είναι λάθος (Διόρθωση: όχι και τα δύο πια) και το τρίτο έχει μια λανθασμένη επιβεβαίωση. Αισθάνομαι ότι έπρεπε να διευκρινίσει τα πράγματα ...

Το 2 πιο δημοφιλή δέντρο είναι AVL και Κόκκινο Μαύρο (RB). Η κύρια διαφορά ψέμα στη χρήση:

  • AVL: Καλύτερα αν λόγος της διαβούλευσης (διαβάστε) είναι μεγαλύτερο από το χειρισμό (τροποποίηση). πόδι μνήμης εκτύπωσης είναι λίγο μικρότερη από ό, τι RB (λόγω του bit που απαιτούνται για χρωματισμό).
  • RB: Καλύτερη σε γενικές περιπτώσεις όπου υπάρχει μια ισορροπία μεταξύ της διαβούλευσης (διαβάστε) και τις πράξεις χειραγώγησης (τροποποίηση) ή περισσότερα τροποποίηση πάνω από διαβούλευση. Μια ελαφρώς μεγαλύτερο αποτύπωμα μνήμης λόγω της αποθήκευση του κόκκινου-μαύρη σημαία.

Η κύρια διαφορά προέρχεται από το χρωματισμό. Θα έχετε λιγότερη ενέργεια εκ νέου ισορροπία στην RB δέντρο από AVL, επειδή το χρώμα σας δίνουν τη δυνατότητα να μερικές φορές παραλείψετε ή να συντομεύσει τις δράσεις εκ νέου την ισορροπία που έχουν σχετική hi κόστος. Λόγω του χρωματισμού, RB δέντρο έχουν επίσης υψηλότερο επίπεδο των κόμβων, διότι θα μπορούσε να δεχθεί κόκκινη κόμβοι μεταξύ μαύρα (με τις δυνατότητες ~ 2 φορές περισσότερα επίπεδα) κάνοντας αναζήτηση (διαβάστε) λίγο λιγότερο αποτελεσματικό ... αλλά επειδή είναι ένα σταθερά (2χ), να παραμείνει σε O (log n).

Αν θεωρείτε το χτύπημα απόδοσης για την τροποποίηση ενός δέντρου (δηλωτικός) VS το χτύπημα απόδοση των διαβουλεύσεων ενός δέντρου (σχεδόν ασήμαντα), θα γίνει φυσικά να προτιμούν RB πάνω AVL για μια γενική περίπτωση.

Απαντήθηκε 30/05/2017 στις 20:33
πηγή χρήστη

ψήφοι
5

Οι προηγούμενες απαντήσεις αντιμετωπίσει μόνο εναλλακτικές λύσεις δέντρο και κόκκινο μαύρο μάλλον παραμένει μόνο για ιστορικούς λόγους.

Γιατί όχι ένα πίνακα κατακερματισμού;

Σε ένα δέντρο ένα είδος απαιτεί μόνο μία μερική διάταξη (<σύγκρισης) που θα χρησιμοποιηθεί ως βασικό στο χάρτη. Ωστόσο, πίνακες κατακερματισμού απαιτούν ότι κάθε τύπος κλειδί έχει μια συνάρτηση κατακερματισμού ορίζεται. Κρατώντας αυτές τις απαιτήσεις τύπου στο ελάχιστο είναι πολύ σημαντικό για τα γενόσημα προγραμματισμού.

Σχεδιάζοντας ένα καλό πίνακα κατακερματισμού απαιτεί βαθιά γνώση του στο πλαίσιο αυτό που θα χρησιμοποιηθεί. Σε περίπτωση που το χρησιμοποιούν ανοικτή αντιμετώπιση, ή συνδέονται με αλυσιδωτή σύνδεση; Τι επίπεδα του φορτίου θα πρέπει να την αποδεχθεί, πριν την αλλαγή μεγέθους; Θα πρέπει να χρησιμοποιήσετε ένα ακριβό κατακερματισμού που αποφεύγει τις συγκρούσεις, ή ένα που είναι τραχιά και γρήγορη;

(C ++ 11 έκανε προσθέσετε πίνακες κατακερματισμού με unordered_map. Μπορείτε να δείτε από την τεκμηρίωση που απαιτεί τον καθορισμό των πολιτικών για να ρυθμίσετε πολλές από αυτές τις επιλογές.)

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

Τι γίνεται με τα άλλα δέντρα;

Η προσφορά γρήγορη αναζήτηση και κόκκινο μαύρο δέντρο που είναι αυτο εξισορρόπησης σε αντίθεση με BSTs. Ένας άλλος χρήστης επεσήμανε τα πλεονεκτήματα της για την αυτο-εξισορρόπησης AVL δέντρο.

Αλέξανδρος Stepanov (Ο δημιουργός της STL), δήλωσε ότι θα χρησιμοποιήσει ένα Β * δέντρο αντί για ένα κόκκινο-μαύρο δέντρο, αν έγραψε std::mapκαι πάλι. Αυτό οφείλεται στο γεγονός ότι οι κόμβοι μπορούν να αποθηκεύσουν έναν αυθαίρετο αριθμό των στοιχείων συνεχόμενα που είναι πιο φιλικό για τις σύγχρονες κρύπτες μνήμης.

Μία από τις μεγαλύτερες αλλαγές από τότε ήταν η αύξηση των κρύπτες. χάνει Cache είναι πολύ δαπανηρή, τόσο τοπικότητα αναφοράς είναι πολύ πιο σημαντικό τώρα. Κόμβος με βάση τις δομές δεδομένων, τα οποία έχουν χαμηλή περιοχή αναφοράς, κάνουν πολύ λιγότερο νόημα. Αν ήμουν σχεδιασμό STL σήμερα, θα είχα ένα διαφορετικό σύνολο των εμπορευματοκιβωτίων. Για παράδειγμα, μια σε μνήμη Β * -δέντρο είναι μια πολύ καλύτερη επιλογή από ένα κόκκινο-μαύρο δέντρο για την εφαρμογή μιας associative δοχείο. - Αλέξανδρος Stepanov

Μπορείτε να διαβάσετε περισσότερα εδώ

Είναι κόκκινο μαύρο δέντρο ή Β * πάντα η καλύτερη;

Σε άλλες περιπτώσεις ο Alex έχει δηλώσει ότι std::vectorείναι σχεδόν πάντα το καλύτερο δοχείο λίστα για παρόμοιους λόγους. Σπάνια έχει νόημα να χρησιμοποιήσει std::listή std::dequeακόμη και για εκείνες τις περιπτώσεις που διδάσκονται στο σχολείο (όπως η αφαίρεση ενός στοιχείου από τη μέση της λίστας). std::vectorείναι τόσο γρήγορη που χτυπάει αυτές τις δομές για τα πάντα, αλλά μεγάλα n.

Εφαρμόζοντας την ίδια συλλογιστική, αν έχετε μόνο ένα μικρό αριθμό στοιχείων (εκατοντάδες;) με τη χρήση std::vectorκαι γραμμική αναζήτηση μπορεί να είναι πιο αποτελεσματική από την εφαρμογή δέντρο της std::map. Ανάλογα με τη συχνότητα της εισαγωγής, μια ταξινομημένη std::vectorσε συνδυασμό με std::binary_searchμπορεί να είναι η ταχύτερη επιλογή.

Απαντήθηκε 22/12/2017 στις 00:46
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more