ํฐ์คํ ๋ฆฌ ๋ทฐ
์ฝ๋ฉ ํ ์คํธ ๋ฌธ์ ๋ฅผ ํ๋ฉด์ PQ(Priority Queue)๋ฅผ ์ง์ ๊ตฌํํ์ฌ์ผ ํ ๊ฒฝ์ฐ๊ฐ ์์๋ค. ๋จ์ํ Parent, Left Child, Right Child์ ์ธ๋ฑ์ค๋ง ์๋ ๊ฒ์ด ์๋๊ณ , push, pop, updaet, erase ๋ชจ๋ ๊ธฐ๋ฅ์ ๋ํด ์ด๋ค ์์ผ๋ก ๋์ํ๋์ง ๊ฐ๋ตํ ์ ๋ฆฌํด๋ณด๊ณ ์ ํ๋ค.
PQ์ ์ฝ์ ํ ๋ฐ์ดํฐ
struct Info {
int idx;
int score;
}
PQ์ ์ฝ์ ํ ๋ฐ์ดํฐ๋ ์ผ๋ฐ ๋ณ์๊ฐ ์๋, ์ฌ์ฉ์ ์ง์ ๋ณ์๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ๋ ฌ์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ๋ฅผ ๋ค๋ฃจ๊ณ ์ ํ๋ค. ์ ๊ตฌ์กฐ์ฒด ์ฒ๋ผ score๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ๋ ์ ๋ ์๊ณ , ๊ฒฝ์ฐ์ ๋ฐ๋ผ ๋ค์ํ ์ฐ์ ์์์ ๋ฐ๋ผ ์ ๋ ฌ์ํฌ ์ ์๋ค. `idx`์ ๊ฒฝ์ฐ, PQ์ push, pop์ ํ ๋๋ ํ์ํ์ง ์์ง๋ง, PQ์ update, erase ํ ๊ฒฝ์ฐ์ ํ์ํ๋ค.
PQ init
void init() {
// size๋ฅผ 0์ผ๋ก ๋ง๋ค๋ฉด top๋ถํฐ ๋ค์ ์ฝ์
ํ๊ฒ ๋๋ค.
size = 0;
}
PQ์ init๋ ๊ฐ๋จํ๋ค. ํ์ฌ ์ฌ์ฉ์ค์ธ heap์ ํฌ๊ธฐ๋ฅผ 0์ผ๋ก ๋ง๋ค์ด๋ฒ๋ฆฌ๋ฉด top๋ถํฐ ๋ค์ ๊ฐ์ ์ฑ์ฐ๊ฒ ๋๋ค.
PQ Push
int updateParent(int idx) {
int curIdx = idx;
// current๊ฐ root๊ฐ ์๋๊ณ , parent ๋
ธ๋๋ณด๋ค ์ฐ์ ์์์ด๋ฉด
while (curIdx > 0 && comp(curIdx, (curIdx - 1) / 2)) {
swap(curIdx, (curIdx - 1) / 2);
curIdx = (curIdx - 1) / 2;
}
return curIdx;
}
void push(Info* r) {
heap[size] = r;
r->idx = size;
updateParent(size);
size++;
}
PQ์ ์๋ก์ด ๊ฐ์ pushํ ๊ฒฝ์ฐ, ํ์ํ๊ณ ์ ํ๋ index๊ฐ root๊ฐ ์๋๊ณ , parent๋ณด๋ค ์ฐ์ ์์๊ฐ ๋์ ๋๊น์ง ๊ณ์ ํ์ํ์ฌ, ํ์ฌ ์ฝ์ ํ ๊ฐ์ ์๋ฆฌ๋ฅผ ์ฐพ์์ผ ํ๋ค. ์ด๋ฅผ ์ํด, `swap`, `comp` ํจ์๋ฅผ ์ ์ํ์ฌ ํธ์ถํ๋ฉด ๋ณด๋ค ๊น๋ํ๊ฒ ์์ฑํ ์ ์๋ค. ์ฌ๊ธฐ์ ์ค์ํ ๊ฒ์ parent์ index๋ `(current index - 1) / 2`๋ผ๋ ๊ฒ์ด๋ค.
PQ pop
void updateChild(int idx) {
int curIdx = idx;
// current๊ฐ ์ผ์ชฝ ์์์ด ์์ ๋ ๊น์ง
while (curIdx * 2 + 1 < size) {
int child;
if (curIdx * 2 + 2 == size)
child = curIdx * 2 + 1;
else
child = comp(curIdx * 2 + 1, curIdx * 2 + 2) ? curIdx * 2 + 1 : curIdx * 2 + 2;
if (comp(curIdx, child))
break;
swap(curIdx, child);
curIdx = child;
}
}
Info* pop() {
if (size == 0)
return nullptr;
Info* top = heap[0];
size--;
swap(0, size);
updateChild(0);
return top;
}
PQ์ top์ popํ๋ ๊ฒฝ์ฐ์๋ 0๋ฒ ์ธ๋ฑ์ค์ ๊ฐ์ return ํ๊ณ , 0๋ฒ๊ณผ ๋ง์ง๋ง ์ธ๋ฑ์ค์ swap ํ ๋ค์, ํด๋น ๊ฐ์ ์์น๋ฅผ ์ฐพ์ผ๋ฉด์ ๋ค์ ์ ๋ ฌํ๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋ค. ์ฌ๊ธฐ์ ์ค์ํ ๊ฒ์ left child๋ `current index * 2 + 1`, right child๋ `current index * 2 + 2`๋ก ์ฐพ์ ์ ์๋ค๋ ๊ฒ์ด๋ค.
PQ update
PQ update๋ heap์ ํน์ ์ธ๋ฑ์ค์ ๋ํ ๊ฐ์ด ์ ๋ฐ์ดํธ ๋๋ฉด, `updateChild(updateParent(idx))`์ ๊ฐ์ด ํน์ ์ธ๋ฑ์ค์ ๋ํ ์์น๋ฅผ ๋ค์ ์ ๋ ฌํ๋ ๋ฐฉ์์ผ๋ก ์งํํ๋ฉด ๋๋ค.
PQ erase
PQ erase๋ pop์ 0๋ฒ ์ธ๋ฑ์ค์ ๋ง์ง๋ง ์ธ๋ฑ์ค๋ฅผ swapํ์๋ค๋ฉด, ์ด์ ๋ฌ๋ฆฌ ํน์ ์ธ๋ฑ์ค์ ๋ง์ง๋ง ์ธ๋ฑ์ค๋ฅผ swap ํ๋ ์ฐจ์ด๋ง ๊ฐ์ง๊ณ ์๋ค. update์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ค๊ฐ ์ธ๋ฑ์ค์ erase๊ฐ ๋ฐ์ํ๋ค๋ฉด, child, parent ๋ชจ๋ ์ ๋ฐ์ดํธํ์ฌ์ผ ํ๋ฏ๋ก `updateChild(updateParent(idx))`์ ๊ฐ์ด ํธ์ถํ์ฌ ๋ค์ ์ ๋ ฌํ๋ ๋ฐฉ์์ผ๋ก ์งํํ๋ค.
์ ์ฒด ์ฝ๋
#define MAX_HEAP 100
struct Info {
int idx;
int score;
};
struct PQ {
/*
* Parent = (idx - 1) / 2
* leftChild = idx * 2 + 1
* rightChild = idx * 2 + 2
*/
int size;
Info* heap[MAX_HEAP];
void init() {
// size๋ฅผ 0์ผ๋ก ๋ง๋ค๋ฉด top๋ถํฐ ๋ค์ ์ฝ์
ํ๊ฒ ๋๋ค.
size = 0;
}
bool comp(int a, int b) {
// ๋ถ๋ฑํธ๋ฅผ ๋ฐ๋๋กํ๋ฉด max heap์ด ๋๋ค.
return heap[a]->score < heap[b]->score;
}
void swap(int a, int b) {
heap[a]->idx = b;
heap[b]->idx = a;
Info* temp = heap[a];
heap[a] = heap[b];
heap[b] = temp;
}
int updateParent(int idx) {
int curIdx = idx;
// current๊ฐ root๊ฐ ์๋๊ณ , parent ๋
ธ๋๋ณด๋ค ์ฐ์ ์์์ด๋ฉด
while (curIdx > 0 && comp(curIdx, (curIdx - 1) / 2)) {
swap(curIdx, (curIdx - 1) / 2);
curIdx = (curIdx - 1) / 2;
}
return curIdx;
}
void updateChild(int idx) {
int curIdx = idx;
// current๊ฐ ์ผ์ชฝ ์์์ด ์์ ๋ ๊น์ง
while (curIdx * 2 + 1 < size) {
int child;
if (curIdx * 2 + 2 == size)
child = curIdx * 2 + 1;
else
child = comp(curIdx * 2 + 1, curIdx * 2 + 2) ? curIdx * 2 + 1 : curIdx * 2 + 2;
if (comp(curIdx, child))
break;
swap(curIdx, child);
curIdx = child;
}
}
void push(Info* r) {
heap[size] = r;
r->idx = size;
updateParent(size);
size++;
}
Info* pop() {
if (size == 0)
return nullptr;
Info* top = heap[0];
size--;
swap(0, size);
updateChild(0);
return top;
}
/*
* update, erase๋ ํน์ ๋ถ๋ถ์์ ์งํ๋๋ฏ๋ก
* parent, child ๋ชจ๋ ์
๋ฐ์ดํธ๋ฅผ ํ์ฌ์ผ ํจ.
*/
void update(Info* r) {
updateChild(updateParent(r->idx));
}
void erase(Info* r) {
int idx = r->idx;
size--;
swap(idx, size);
updateChild(updateParent(idx));
}
};
์ ์ฒด ์ฝ๋๋ ์์ ๊ฐ๋ค. ๋ฐ์ดํฐ์ ์ฝ์ , ์ญ์ , ๊ฐฑ์ ์ ๋ฐ๋ผ parent, child๋ฅผ ์ ๋ฐ์ดํธํ ์ง ์๊ณ , ์ด๋ฅผ ํ์ํ๊ธฐ ์ํ ๋ก์ง์ ์ํดํ๋ค๋ฉด ์ฝ๊ฒ ์์ฑํ ์ ์๋ค. update, erase๋ฅผ ์ํด์๋ ํจ์๋ฅผ ์ ๊ตฌ๋ถํ์ฌ ๊ตฌํํ๋ ๊ฒ๋ ์ค์ํ ๊ฒ ๊ฐ๋ค.
'๐โโ๏ธ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด > C++' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
c++: ํ์ ํํ์ ๊ตฌํํ๊ธฐ (0) | 2022.02.20 |
---|---|
C++: substr, split ํ์ฉํ๊ธฐ (0) | 2022.02.13 |
C++: Trie ๊ตฌํํ๊ธฐ (0) | 2022.01.30 |