Sobes.tech
Middle

Πότε πρέπει να χρησιμοποιείτε std::set και πότε std::unordered_set σε C++;

sobes.tech AI

Απάντηση από AI

Το std::set και το std::unordered_set χρησιμοποιούνται για την αποθήκευση μοναδικών στοιχείων. Η επιλογή μεταξύ τους εξαρτάται από τις προτεραιότητες: ταξινόμηση ή απόδοση πρόσβασης/εισαγωγής/διαγραφής.

Το std::set βασίζεται σε ένα ισορροπημένο δυαδικό δέντρο αναζήτησης (συνήθως ένα κόκκινο-μαύρο δέντρο).

Χαρακτηριστικά του std::set:

  • Τα στοιχεία αποθηκεύονται σε ταξινομημένη σειρά.
  • Η εισαγωγή, διαγραφή και αναζήτηση στοιχείων διαρκεί κατά μέσο όρο O(log N), όπου N είναι ο αριθμός των στοιχείων.
  • Κατάλληλο όταν η ταξινομημένη σειρά των στοιχείων είναι σημαντική ή όταν απαιτείται η λήψη στοιχείων σε συγκεκριμένο εύρος.

Το std::unordered_set βασίζεται σε έναν πίνακα κατακερματισμού.

Χαρακτηριστικά του std::unordered_set:

  • Τα στοιχεία δεν αποθηκεύονται σε ταξινομημένη σειρά.
  • Η εισαγωγή, διαγραφή και αναζήτηση στοιχείων διαρκεί κατά μέσο όρο O(1), αλλά στην χειρότερη περίπτωση (με πολλές συγκρούσεις στη συνάρτηση κατακερματισμού) μπορεί να φτάσει το O(N).
  • Απαιτεί ο τύπος του στοιχείου να έχει μια ορισμένη συνάρτηση κατακερματισμού (std::hash) και τελεστή σύγκρισης ισότητας (operator==).
  • Κατάλληλο όταν απαιτείται η μέγιστη ταχύτητα εισαγωγής, διαγραφής και αναζήτησης, και η σειρά των στοιχείων δεν έχει σημασία.

Πίνακας σύνοψης:

Κριτήριο std::set std::unordered_set
Εσωτερική δομή Ισορροπημένο δέντρο Πίνακας κατακερματισμού
Σειρά στοιχείων Ταξινομημένη Μη ταξινομημένη
Χρόνος αναζήτησης/εισαγωγής/διαγραφής (μέσος όρος) O(log N) O(1)
Χρόνος αναζήτησης/εισαγωγής/διαγραφής (χειρότερη περίπτωση) O(log N) O(N)
Απαιτήσεις τύπου Τελεστής < std::hash, operator==

Παράδειγμα χρήσης του std::set:

#include <iostream>
#include <set>

int main() {
    std::set<int> ταξινομημένο_set;
    ταξινομημένο_set.insert(5);
    ταξινομημένο_set.insert(2);
    ταξινομημένο_set.insert(8);

    // Τα στοιχεία εμφανίζονται με ταξινομημένη σειρά: 2 5 8
    for (int τιμή : ταξινομημένο_set) {
        std::cout << τιμή << " ";
    }
    std::cout << std::endl;

    return 0;
}

Παράδειγμα χρήσης του std::unordered_set:

#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> μη_ταξινομημένο_set;
    μη_ταξινομημένο_set.insert(5);
    μη_ταξινομημένο_set.insert(2);
    μη_ταξινομημένο_set.insert(8);

    // Η σειρά εμφάνισης μπορεί να διαφέρει
    for (int τιμή : μη_ταξινομημένο_set) {
        std::cout << τιμή << " ";
    }
    std::cout << std::endl;

    return 0;
}