Middle
Kada naudoti std::set ir kada std::unordered_set C++?
sobes.tech AI
Atsakymas iš AI
std::set ir std::unordered_set naudojami saugoti unikalius elementus. Pasirinkimas tarp jų priklauso nuo prioritetų: tvarkos ar našumo prieigos/pridėjimo/ištrynimo.
std::set pagrįstas subalansuotu dvejetainiu paieškos medžiu (dažniausiai raudonai-juodu medžiu).
std::set ypatybės:
- Elementai saugomi surūšiuotoje tvarkoje.
- Pridėjimas, ištrynimas ir paieška trunka O(log N) laiką, kur N yra elementų skaičius.
- Tinka, kai svarbu surūšiuota elementų tvarka arba kai reikia gauti elementus tam tikrame intervale.
std::unordered_set pagrįstas maišų lentele.
std::unordered_set ypatybės:
- Elementai nėra saugomi surūšiuotoje tvarkoje.
- Pridėjimas, ištrynimas ir paieška vidutiniškai trunka O(1), bet blogiausiu atveju (kai yra daug kolizijų) gali pasiekti O(N).
- Reikalaujama, kad elemento tipas turėtų apibrėžtą maišų funkciją (
std::hash) ir lyginimo operatorių (operator==). - Tinka, kai reikalingas maksimalus greitis pridėjimui, ištrynimui ir paieškai, o tvarka nėra svarbi.
Lentelė:
| Kriterijus | std::set |
std::unordered_set |
|---|---|---|
| Vidinė struktūra | Subalansuotas medis | Maišų lentelė |
| Elementų tvarka | Surūšiuota | Nesurūšiuota |
| Laikas paieškai/pridėjimui/ištrynimui (vidutinis) | O(log N) | O(1) |
| Laikas paieškai/pridėjimui/ištrynimui (blogiausias) | O(log N) | O(N) |
| Reikalavimai tipui | < operatorius |
std::hash, operator== |
Pavyzdys std::set naudojimui:
#include <iostream>
#include <set>
int main() {
std::set<int> surūšiuotas_set;
surūšiuotas_set.insert(5);
surūšiuotas_set.insert(2);
surūšiuotas_set.insert(8);
// Elementai išvedami surūšiuotoje tvarkoje: 2 5 8
for (int reikšmė : surūšiuotas_set) {
std::cout << reikšmė << " ";
}
std::cout << std::endl;
return 0;
}
Pavyzdys std::unordered_set naudojimui:
#include <iostream>
#include <unordered_set>
int main() {
std::unordered_set<int> nesurūšiuotas_set;
nesurūšiuotas_set.insert(5);
nesurūšiuotas_set.insert(2);
nesurūšiuotas_set.insert(8);
// Išvedimo tvarka gali būti kitokia
for (int reikšmė : nesurūšiuotas_set) {
std::cout << reikšmė << " ";
}
std::cout << std::endl;
return 0;
}