deque și
priority_queue din STL
deque<T> -
coadă cu două capete
#include <deque>
using namespace std;
deque<int> dq;
dq.push_back(3); // adaugă la spate: [3]
dq.push_back(7); // [3, 7]
dq.push_front(1); // adaugă în față: [1, 3, 7]
cout << dq.front(); // 1
cout << dq.back(); // 7
cout << dq[1]; // 3 (acces prin indice)
dq.pop_front(); // scoate din față: [3, 7]
dq.pop_back(); // scoate din spate: [3]
cout << dq.size(); // 1Operații
| Operație | Ce face | Complexitate |
|---|---|---|
push_back(x) |
Adaugă la spate | O(1) |
push_front(x) |
Adaugă în față | O(1) |
pop_back() |
Scoate din spate | O(1) |
pop_front() |
Scoate din față | O(1) |
front() |
Primul element | O(1) |
back() |
Ultimul element | O(1) |
dq[i] |
Acces prin indice | O(1) |
size() |
Număr elemente | O(1) |
empty() |
Verifică gol | O(1) |
Exemplu: minim pe fereastră glisantă
#include <fstream>
#include <deque>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int v[100001];
int n, k;
int main()
{
fin >> n >> k;
for (int i = 1; i <= n; i++)
fin >> v[i];
deque<int> dq; // stocăm indici
for (int i = 1; i <= n; i++) {
while (!dq.empty() && dq.front() < i - k + 1)
dq.pop_front();
while (!dq.empty() && v[dq.back()] >= v[i])
dq.pop_back();
dq.push_back(i);
if (i >= k)
fout << v[dq.front()] << " ";
}
return 0;
}Identic cu implementarea manuală, dar mai curat.
priority_queue<T>
- coadă de priorități
priority_queue este un max-heap
implicit: elementul cel mai mare e mereu în vârf.
#include <queue> // priority_queue e tot în <queue>
using namespace std;
priority_queue<int> pq;
pq.push(3);
pq.push(7);
pq.push(2);
pq.push(9);
cout << pq.top(); // 9 (maximul)
pq.pop(); // scoate 9
cout << pq.top(); // 7
cout << pq.size(); // 3Operații
| Operație | Ce face | Complexitate |
|---|---|---|
push(x) |
Inserează element | O(log n) |
pop() |
Scoate maximul | O(log n) |
top() |
Returnează maximul | O(1) |
size() |
Număr elemente | O(1) |
empty() |
Verifică gol | O(1) |
Min-heap cu
priority_queue
Implicit e max-heap. Pentru min-heap, folosim
greater<int>:
priority_queue<int, vector<int>, greater<int>> pq;
pq.push(3);
pq.push(7);
pq.push(2);
cout << pq.top(); // 2 (minimul!)Declarația e mai lungă dar funcționează identic, doar că vârful e minimul.
Truc rapid: dacă nu vrei să memorezi
declarația pentru min-heap, poți insera valorile
negate: push -x în max-heap, și
top va fi -max = min. La extragere, negăm
înapoi.
Exemplu: cele mai mici K elemente
#include <fstream>
#include <queue>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int main()
{
int n, k;
fin >> n >> k;
priority_queue<int, vector<int>, greater<int>> pq;
for (int i = 1; i <= n; i++) {
int x;
fin >> x;
pq.push(x);
}
for (int i = 1; i <= k; i++) {
fout << pq.top() << " ";
pq.pop();
}
return 0;
}date.in:
8 3
5 3 8 1 9 2 7 4date.out:
1 2 3Priority queue cu
pair
Putem stoca perechi. Sortarea e după .first,
apoi .second:
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
pq.push({5, 1}); // (cost, nod)
pq.push({2, 3});
pq.push({7, 2});
cout << pq.top().first << " " << pq.top().second; // 2 3 (minimul după cost)Aceasta e baza algoritmului Dijkstra pentru drumuri minime în grafuri.
Exemplu: interclasarea a K vectori sortați
Avem K vectori sortați, vrem să îi combinăm într-unul singur, sortat. Folosim un min-heap cu perechea (valoare, indexul vectorului).
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int main()
{
int k;
fin >> k;
vector<vector<int>> vecs(k);
vector<int> poz(k, 0); // poziția curentă în fiecare vector
for (int i = 0; i < k; i++) {
int n;
fin >> n;
vecs[i].resize(n);
for (int j = 0; j < n; j++)
fin >> vecs[i][j];
}
// Min-heap: (valoare, index_vector)
priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
// Inserăm primul element din fiecare vector
for (int i = 0; i < k; i++)
if (!vecs[i].empty())
pq.push({vecs[i][0], i});
while (!pq.empty()) {
int val = pq.top().first;
int idx = pq.top().second;
pq.pop();
fout << val << " ";
poz[idx]++;
if (poz[idx] < (int)vecs[idx].size())
pq.push({vecs[idx][poz[idx]], idx});
}
return 0;
}Comparație
stack |
queue |
deque |
priority_queue |
|
|---|---|---|---|---|
| Adaugă | vârf | spate | ambele | auto-sortat |
| Scoate | vârf | față | ambele | max/min |
| Acces | top | front | ambele + indice | top |
| Ordine | LIFO | FIFO | ambele | Heap |
Greșeli frecvente
1.
priority_queue e max-heap implicit
priority_queue<int> pq;
pq.push(1); pq.push(5); pq.push(3);
cout << pq.top(); // 5, NU 1!Pentru min-heap:
priority_queue<int, vector<int>, greater<int>>.
2. pop() nu
returnează valoare
La toate structurile STL, pop() returnează
void. Citim cu top() /
front() înainte.
3. Include greșit
priority_queue și queue sunt ambele
în <queue>. deque e în
<deque>.
Ce să reții
deque<T>: push/pop la ambele capete + acces prin indice. Ideal pentru fereastră glisantă.priority_queue<T>: max-heap implicit. Cugreater<T>devine min-heap.priority_queuecupaire baza lui Dijkstra.pop()nu returnează valoare la nicio structură STL.