Jaka jest różnica między nimi? Chodzi mi o to, że metody są takie same. Więc dla użytkownika działają identycznie.
Czy to jest poprawne??
Odpowiedzi:
Z (przestarzałego, ale nadal bardzo przydatnego) podsumowania SGI STLdeque
:
Deque jest bardzo podobny do wektora: podobnie jak wektor, jest to sekwencja, która obsługuje losowy dostęp do elementów, wstawianie i usuwanie elementów w stałym czasie na końcu sekwencji oraz wstawianie i usuwanie elementów w środku w czasie liniowym.
Głównym sposobem, w jaki deque różni się od wektora, jest to, że deque obsługuje również wstawianie i usuwanie elementów w stałym czasie na początku sekwencji. Ponadto deque nie ma żadnych funkcji składowych analogicznych do funkcji capacity () i booking () wektora i nie zapewnia żadnych gwarancji dotyczących ważności iteratora, które są skojarzone z tymi funkcjami składowymi.
Oto podsumowanie list
z tej samej witryny:
Lista to lista podwójnie połączona. Oznacza to, że jest to Sekwencja, która obsługuje zarówno przechodzenie do przodu, jak i do tyłu oraz (amortyzowane) stałe wstawianie i usuwanie elementów na początku lub na końcu lub w środku. Listy mają ważną właściwość polegającą na tym, że wstawianie i łączenie nie unieważnia iteratorów do elementów listy, a nawet usunięcie unieważnia tylko iteratory wskazujące na elementy, które są usuwane. Kolejność iteratorów może ulec zmianie (to znaczy list :: iterator może mieć innego poprzednika lub następcę po operacji na liście niż poprzednio), ale same iteratory nie zostaną unieważnione ani nie będą wskazywać na inne elementy, chyba że to unieważnienie lub mutacja jest wyraźna.
Podsumowując, kontenery mogą mieć wspólne procedury, ale gwarancje czasowe dla tych procedur różnią się w zależności od kontenera . Jest to bardzo ważne, gdy zastanawiasz się, którego z tych kontenerów użyć do wykonania zadania: uwzględnienie tego, jak kontener będzie najczęściej używany (np. Bardziej do wyszukiwania niż do wstawiania / usuwania) znacznie ułatwia kierowanie do odpowiedniego kontenera .
Wypiszę różnice:
Złożoność
Insert/erase at the beginning in middle at the end
Deque: Amortized constant Linear Amortized constant
List: Constant Constant Constant
constant
i amortized constant
?
std::list
jest w zasadzie podwójnie połączoną listą.
std::deque
z drugiej strony jest implementowany bardziej podobnie std::vector
. Ma stały czas dostępu według indeksu, a także wstawianie i usuwanie na początku i na końcu, co zapewnia dramatycznie inną charakterystykę wydajności niż lista.
Kolejną ważną gwarancją jest sposób, w jaki każdy kontener przechowuje swoje dane w pamięci:
Zauważ, że deque został zaprojektowany, aby spróbować zrównoważyć zalety zarówno wektora, jak i listy, bez ich odpowiednich wad. Jest to szczególnie interesujący pojemnik w platformach o ograniczonej pamięci, na przykład mikrokontrolerach.
Strategia przechowywania pamięci jest często pomijana, jednak często jest to jeden z najważniejszych powodów, dla których należy wybrać najbardziej odpowiedni kontener dla określonej aplikacji.
Nie. Deque obsługuje tylko wstawianie i usuwanie O (1) z przodu iz tyłu. Może być na przykład zaimplementowany w wektorze z zawijaniem. Ponieważ gwarantuje również dostęp losowy O (1), możesz być pewien, że nie używa (tylko) podwójnie połączonej listy.
Różnice w wydajności zostały dobrze wyjaśnione przez innych. Chciałem tylko dodać, że podobne lub nawet identyczne interfejsy są powszechne w programowaniu obiektowym - część ogólnej metodologii pisania oprogramowania zorientowanego obiektowo. NIE POWINIENEŚ w ŻADNY sposób zakładać, że dwie klasy działają w ten sam sposób po prostu dlatego, że implementują ten sam interfejs, tak samo jak nie powinieneś zakładać, że koń działa jak pies, ponieważ obie implementują attack () i make_noise ().
Oto kod sprawdzający koncepcję użycia listy, nieuporządkowanej mapy, która zapewnia wyszukiwanie O (1) i dokładne utrzymanie LRU O (1). Potrzebuje (nieusuniętych) iteratorów, aby przetrwać operacje wymazywania. Zaplanuj użycie w O (1) dowolnie dużej pamięci podręcznej zarządzanej programowo dla wskaźników procesora w pamięci GPU. Wskazuje na program planujący Linux O (1) (kolejka uruchomień LRU <-> na procesor). Unordered_map ma stały dostęp do czasu poprzez tablicę skrótów.
#include <iostream>
#include <list>
#include <unordered_map>
using namespace std;
struct MapEntry {
list<uint64_t>::iterator LRU_entry;
uint64_t CpuPtr;
};
typedef unordered_map<uint64_t,MapEntry> Table;
typedef list<uint64_t> FIFO;
FIFO LRU; // LRU list at a given priority
Table DeviceBuffer; // Table of device buffers
void Print(void){
for (FIFO::iterator l = LRU.begin(); l != LRU.end(); l++) {
std::cout<< "LRU entry "<< *l << " : " ;
std::cout<< "Buffer entry "<< DeviceBuffer[*l].CpuPtr <<endl;
}
}
int main()
{
LRU.push_back(0);
LRU.push_back(1);
LRU.push_back(2);
LRU.push_back(3);
LRU.push_back(4);
for (FIFO::iterator i = LRU.begin(); i != LRU.end(); i++) {
MapEntry ME = { i, *i};
DeviceBuffer[*i] = ME;
}
std::cout<< "************ Initial set of CpuPtrs" <<endl;
Print();
{
// Suppose evict an entry - find it via "key - memory address uin64_t" and remove from
// cache "tag" table AND LRU list with O(1) operations
uint64_t key=2;
LRU.erase(DeviceBuffer[2].LRU_entry);
DeviceBuffer.erase(2);
}
std::cout<< "************ Remove item 2 " <<endl;
Print();
{
// Insert a new allocation in both tag table, and LRU ordering wiith O(1) operations
uint64_t key=9;
LRU.push_front(key);
MapEntry ME = { LRU.begin(), key };
DeviceBuffer[key]=ME;
}
std::cout<< "************ Add item 9 " <<endl;
Print();
std::cout << "Victim "<<LRU.back()<<endl;
}
Wśród znaczących różnic między deque
ilist
Dla deque
:
Przedmioty przechowywane obok siebie;
Zoptymalizowany pod kątem dodawania danych z dwóch stron (przód, tył);
Elementy indeksowane liczbami (liczbami całkowitymi).
Można przeglądać za pomocą iteratorów, a nawet według indeksu elementu.
Czasowy dostęp do danych jest szybszy.
Dla list
Pozycje przechowywane „losowo” w pamięci;
Można przeglądać tylko przez iteratory;
Zoptymalizowany do wkładania i wyjmowania w środku.
Dostęp czasowy do danych jest wolniejszy, iteruje powoli ze względu na bardzo słabą lokalność przestrzenną.
Bardzo dobrze radzi sobie z dużymi elementami
Możesz również sprawdzić poniższy link , który porównuje wydajność między dwoma kontenerami STL (ze std :: vector)
Mam nadzieję, że podzieliłem się kilkoma przydatnymi informacjami.