Sobes.tech
Middle

Kedy použiť std::set a kedy std::unordered_set v C++?

sobes.tech AI

Odpoveď od AI

std::set a std::unordered_set sa používajú na ukladanie jedinečných prvkov. Výber medzi nimi závisí od priorít: usporiadanie alebo výkon prístupu/vkladania/odstraňovania.

std::set je založené na vyváženom binárnom vyhľadávacom strome (zvyčajne červeno-čiernom strome).

Charakteristiky std::set:

  • Prvky sú uložené v zoradenom poradí.
  • Vkladanie, odstraňovanie a vyhľadávanie prvkov trvá v čase O(log N), kde N je počet prvkov.
  • Je vhodné, keď je dôležité zoradené poradie prvkov alebo keď je potrebné získať prvky v určitom rozsahu.

std::unordered_set je založené na hash tabuľke.

Charakteristiky std::unordered_set:

  • Prvky nie sú uložené v zoradenom poradí.
  • Vkladanie, odstraňovanie a vyhľadávanie prvkov trvá v priemere v čase O(1), ale v najhoršom prípade (pri veľkom počte kolízií hash funkcie) môže dosiahnuť O(N).
  • Vyžaduje, aby mal typ prvku definovanú hash funkciu (std::hash) a operátor porovnania na rovnosť (operator==).
  • Je vhodné, keď je potrebná maximálna rýchlosť vkladania, odstraňovania a vyhľadávania a poradie prvkov nie je dôležité.

Prehľadná tabuľka:

Kritérium std::set std::unordered_set
Vnútorná štruktúra Vyvážené strom Hash tabuľka
Poradie prvkov Zoradené Nezoradené
Čas vyhľadávania/vkladania/odstraňovania (priemer) O(log N) O(1)
Čas vyhľadávania/vkladania/odstraňovania (najhorší prípad) O(log N) O(N)
Požiadavky na typ Operator < std::hash, operator==

Príklad použitia std::set:

#include <iostream>
#include <set>

int main() {
    std::set<int> zoradený_set;
    zoradený_set.insert(5);
    zoradený_set.insert(2);
    zoradený_set.insert(8);

    // Prvky budú vypísané v zoradenom poradí: 2 5 8
    for (int hodnota : zoradený_set) {
        std::cout << hodnota << " ";
    }
    std::cout << std::endl;

    return 0;
}

Príklad použitia std::unordered_set:

#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> neusporiadaný_set;
    neusporiadaný_set.insert(5);
    neusporiadaný_set.insert(2);
    neusporiadaný_set.insert(8);

    // Poradie výstupu môže byť odlišné
    for (int hodnota : neusporiadaný_set) {
        std::cout << hodnota << " ";
    }
    std::cout << std::endl;

    return 0;
}