- Hybryda listy oraz wektora
-
dequedzieli się na kawałki (ang. chunk), które są tablicami porozrzucanymi po pamięci - Rozmiar takiego kawałka zależy od kompilatora i implementacji biblioteki standardowej (nie ma jednej reguły)
-
Dodatkowo deque posiada jeszcze jeden wektor, który przechowuje wskaźniki wskazujące początek każdego
chunkaw pamięci. -
W ten sposób zyskujemy 2 rzeczy:
- Dodawanie nowego elementu jest szybsze, bo alokujemy co najwyżej pamięć dla jednego, całego
chunkai nie będziemy przenosić elementów jak wstd::vector<T>, gdy zabraknie nam miejsca na alokacje dodatkowej pamięci - Dane załadowane z jednego
chunkasą cache-friendly
- Dodawanie nowego elementu jest szybsze, bo alokujemy co najwyżej pamięć dla jednego, całego
-
Częściowo cache-friendly, czyli poszczególne
chunkiznajdą się w pamięci podręcznej procesora -
Typ
Tmoże być dowolny. Zarówno typ wbudowany jakint,double, jak i własny zdefiniowany przez nas typ -
Każdy
chunkjest reprezentowany w pamięci jak tablica, natomiast samechunkinie sąsiadują ze sobą i są porozrzucane jak węzły listy -
Dodanie nowego elementu jest szybkie
- Jeżeli dany
chunkma jeszcze miejsce to dopisujemy go na koniec - Jeżeli nie, to alokowany jest nowy chunk i tam wpisywany jest nowy element
- Jeżeli dany
-
Usuwanie z początku i końca jest szybkie, bo powoduje jedynie przesunięcie iteratorów
begin()lubend() - Usuwanie elementów ze środka jest kosztowne
-
Odczyt i modyfikacja jest szybka
- Znamy rozmiar
chunka, więc wiemy dokładnie, z którego pola w naszym wektorze pomocniczym powinniśmy odczytać adreschunka - Wiemy także, z którego pola odczytać daną, gdyż
chunkjest ułożony jak tablica.
- Znamy rozmiar
Matematycznie ujmując: jeżeli chunk ma 16 elementów a my chcemy dostać się do 100 elementu to:
x = 100 / 16 -> x = 6(ucinamy część po przecinku)y = 100 % 16 -> y = 4
Zatem wiemy, że jest to 4-ty element w 6-tym chunku.
Ta wiedza jest zupełnie niepotrzebna przy użytkowaniu std::deque. Kontener zajmuje się tym automatycznie.
| Operacje | Metody |
|---|---|
| dodawanie elementu | push_back(), emplace_back(), push_front(), emplace_front(), insert(), emplace() |
| modyfikowanie/dostęp do elementu | at(), operator[] |
| pierwszy/ostatni element | back(), front() |
| rozmiar | size() |
| wyczyszczenie nieużywanej pamięci | shrink_to_fit(), |
| odwrócony (ang. reverse) iterator | rbegin(), rend() |
| stały iterator | cbegin(), cend(), crbegin(), crend() |
| wyczyszczenie kontenera | clear() |
| przygotowanie elementu do usunięcia | remove() (nie jest metodą std::deque), |
| wymazanie elementów z pamięci | erase() |
#include <iostream>
#include <deque>
int main() {
std::deque<int> d = {7, 5, 16, 8};
d.push_front(13);
d.push_back(25);
for(const auto& n : d) {
std::cout << n << ' ';
}
std::cout << '\n';
}Output:
13 7 5 16 8 25
- Znajdź dokumentację
std::dequena cppreference.com - Stwórz nowy plik i napisz funkcję
main() - Stwórz pusty
deque - Dodaj do niego 5 dowolnych wartości
- Wyświetl
deque - Usuń 2-gi i 4-ty element
- Dodaj na początek i koniec wartość 30
- Wyświetl
deque - Dodaj na 4 pozycji liczbę 20
- Wyświetl
deque
