ํ์ ๋ ฌ
์ด๋ฒ์๋ ํ ์ ๋ ฌ์ ๋ํด ์์๋ณด์. ํ์ ๋ ฌ์ด๋ ํํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ๋ ์ ๋ ฌ๋ฐฉ๋ฒ์ด๋ค. ์ด๋ฅผ ์ดํดํ๊ธฐ ์ํด์ ๋จผ์ ํ(Heap)๊ตฌ์กฐ๋ฅผ ์์์ผํ๊ณ , ํ์ ์๊ธฐ ์ด์ ์๋ ์ด์ง ํธ๋ฆฌ(Binary Tree)์ ๋ํด ์์์ผ ํ๋ค.
์ด์ง ํธ๋ฆฌ(binary tree)๋ ๊ฐ๊ฐ์ ๋ ธ๋๊ฐ ์ต๋ ๋ ๊ฐ์ ์์ ๋ ธ๋๋ฅผ ๊ฐ์ง๋ ํธ๋ฆฌ ์๋ฃ๊ตฌ์กฐ๋ก, ์์ ๋ ธ๋๋ฅผ ๊ฐ๊ฐ ์ผ์ชฝ์์ ๋ ธํธ์ ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋ ๋ผ๊ณ ํ๋ค.
(์ถ์ฒ : https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%ED%8A%B8%EB%A6%AC)
์์ ์ด์งํธ๋ฆฌ๋ ๋ฐ์ดํฐ๊ฐ ๋ฃจํธ(Root) ๋ ธ๋๋ถํฐ ์์ํด์ ์์๋ ธ๋๊ฐ ์ผ์ชฝ ์์๋ ธ๋, ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋๋ก ์ฐจ๊ทผ์ฐจ๊ทผ ๋ค์ด๊ฐ๋ ๊ตฌ์กฐ์ ์ด์ง ํธ๋ฆฌ์ด๋ค. ์ฆ ์์ ์ด์งํธ๋ฆฌ๋ ์ด์งํธ๋ฆฌ์ ๋ ธ๋๊ฐ ์ค๊ฐ์ ๋น์ด์์ง ์๊ณ , ๋นฝ๋บตํ๊ฒ ๊ฐ๋ ์ฐฌ ๊ตฌ์กฐ์ด๋ค. ๋ ธ๋๊ฐ ์ฝ์ ๋ ๋๋ ํญ์ ์ผ์ชฝ ์์๋ ธ๋๋ถํฐ ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ๋ค.
ํ(Heap)์ ์ต์๊ฐ์ด๋ ์ต๋๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์๋ด๊ธฐ ์ํด ์์ ์ด์งํธ๋ฆฌ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ํธ๋ฆฌ์ด๋ค. ํ์ ์ต๋ ํ๊ณผ ์ต์ ํ์ด ์กด์ฌํ๋๋ฐ ์ต๋ ํ์ '๋ถ๋ชจ ๋ ธ๋'๊ฐ '์์ ๋ ธ๋'๋ณด๋ค ํฐ ํ์ด๊ณ , ์ต์ ํ์ '์์ ๋ ธ๋'๊ฐ '๋ถ๋ชจ ๋ ธ๋'๋ณด๋ค ํฐ ํ์ด๋ค. ์ผ๋จ ํ ์ ๋ ฌ์ ํ๊ธฐ ์ํด์๋ ์ ํด์ง ๋ฐ์ดํฐ๋ฅผ ํ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋๋ก ๋ง๋ค์ด์ผ ํ๋ค.
ํ ์ ๋ ฌ์ ์ํํ๊ธฐ ์ํด์๋ ํ ์์ฑ ์๊ณ ๋ฆฌ์ฆ (Heapify Algorithm)์ ์ฌ์ฉํ๋ค. ํ ์์ฑ ์๊ณ ๋ฆฌ์ฆ์ ํน์ ํ 'ํ๋์ ๋ ธ๋'์ ๋ํด ์ํํ๋ฉฐ, ํด๋น๋๋ 'ํ๋์ ๋ ธ๋๋ฅผ ์ ์ธํ๊ณ ๋ ์ต๋ ํ์ด ๊ตฌ์ฑ๋์ด ์๋ ์ํ'๋ผ๊ณ ๊ฐ์ ์ ํ๋ค๋ ํน์ง์ด ์๋ค. ํ ์์ฑ ์๊ณ ๋ฆฌ์ฆ (Heapify Algorithm)์ด๋ ํน์ ํ ๋ ธ๋์ ๋ ์์ ์ค์์ ๋ ํฐ ์์ ๋ ธ๋์ ์์ ์ ์์น๋ฅผ ๋ฐ๊พธ๋ ์๊ณ ๋ฆฌ์ฆ์ด๋ค. ๋ํ ์์น๋ฅผ ๋ฐ๊พผ ๋ค์๋ ์์๋ ธ๋๊ฐ ์กด์ฌํ๋ค๋ฉด, ๋ ์์ ์ค์์ ๋ ํฐ ์์๊ณผ ์์ ์ ์์น๋ฅผ ๋ฐ๊ฟ์ผ ํ๋ค. ํ ์์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋๋ O(log N)์ด๋ค.
๋ค์์ ์ซ์๋ค์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ๋ ํ๋ก๊ทธ๋จ์ ์์ฑํ์ธ์.
7 6 5 8 3 5 1 9 6
#include <stdio.h>
#pragma warning(disable:4996)
int number = 9;
int heap[9] = { 7, 6, 5, 8, 3, 5, 9, 1, 6 };
int main(void) {
//ํ์ ๊ตฌ์ฑ
//๋จผ์ ์ ์ฒด ํธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ต๋ ํ ๊ตฌ์กฐ๋ก ๋ฐ๊ฟ๋๋ค. (Heapify)
for (int i = 1; i < number; i++) { // ์ ์ฒด ์์์ ๋ํด์ (1~8 -> ๋ง์ง๋ง ํ๊ฐ๋ ์๋์ผ๋ก ๋๋ฏ๋ก)
int c = i;
do {
int root = (c - 1) / 2; //ํน์ ํ ์์์ ๋ถ๋ชจ ๋
ธ๋
if (heap[root] < heap[c]) { //๋ถ๋ชจ์ ๊ฐ๋ณด๋ค ์์์ ๊ฐ์ด ๋ ํฌ๋ค๋ฉด?
int tmp = heap[root]; // ์๋ก ์๋ฆฌ๋ฅผ ๋ฐ๊ฟ
heap[root] = heap[c];
heap[c] = tmp;
for (int i = 0; i < number; i++) {
printf("%d ", heap[i]);
}
printf("\n");
}
c = root; //์์์ ๋ถ๋ชจ๋
ธ๋๋ก ์ด๋ํด์ ๋ฐ๋ณต์ ์ผ๋ก ์ํ
} while (c != 0); // c๊ฐ root๋
ธ๋ (๋งจ์)์ ์ค๊ฒ ๋๋ฉด ๋ฐ๋ณต๋ฌธ ์ ์ง
}
//ํฌ๊ธฐ๋ฅผ ์ค์ฌ๊ฐ๋ฉฐ ๋ฐ๋ณต์ ์ผ๋ก ํ์ ๊ตฌ์ฑ
for (int i = number - 1; i >= 0; i--) {
int temp = heap[0];
heap[0] = heap[i];
heap[i] = temp; //ํฐ๊ฐ์ ๋ค๋ก ๋ณด๋ด๊ธฐ
int root = 0;
int c = 1;
do {
c = 2 * root + 1;
//์์์ค์ ๋ ํฐ ๊ฐ์ ์ฐพ๊ธฐ
if (heap[c] < heap[c + 1] && c < i - 1) {
c++;
}
//๋ฃจํธ๋ณด๋ค ์์์ด ๋ ํฌ๋ค๋ฉด ๊ตํ
if (heap[root] < heap[c] && c < i) {
int temp = heap[root];
heap[root] = heap[c];
heap[c] = temp;
for (int i = 0; i < number; i++) {
printf("%d ", heap[i]);
}
printf("\n");
}
root = c;
} while (c < i);
}
}
์์ ์ด์งํธ๋ฆฌ๋ฅผ ํํํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋ฐฐ์ด์ ์ด์ฉํ๋ ๊ฒ์ด๋ค. ํ์ฌ ์ ๋ ฌํ ๋ฐ์ดํฐ์ ๊ฐฏ์๊ฐ 9๊ฐ์ด๋ฏ๋ก index 0๋ฒ๋ถํฐ 8๋ฒ๊น์ง ์ฐจ๋ก๋๋ก ๋ฐฐ์ด์ ๋ด์ผ๋ฉด ๊ฐ ๋ ธ๋ ๋ฒํธ์ ํด๋นํ๋ ์ซ์๊ฐ ๋ค์ด๊ฐ๋ค๊ณ ์๊ฐํ ์ ์๋ค. ์ดํ ํ ์์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์ํํด ์ต๋ ํ ํํ๋ก ๋ณํ์ ์ํํ๋ค. ์ต๋ ํ ํํ๋ก ๋ณํ์ ํ๊ฒ ๋๋ฉด ๊ฐ์ฅ ํฐ ์๊ฐ root ๋ ธ๋์ ์จ ๊ฑธ ํ์ธํ ์ ์๋๋ฐ, root์ ์๋ ๊ฐ์ ๊ฐ์ฅ ๋ค์ชฝ์ผ๋ก ๋ณด๋ด๊ณ ํ ํธ๋ฆฌ์ ํฌ๊ธฐ๋ฅผ 1์ฉ ๋นผ์ ๋จ์ ์์๋ค๋ก ํ ์์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์ํํ๋ค. ์ด๋ ๊ฒ ๋๋ฉด ๊ฐ์ฅ ๋ค์ชฝ์ผ๋ก ๋ณด๋ธ ์์๋ ๊ณ ์ ๋๊ณ ๋ฐฐ์ด์ ๋๋ถํฐ ํฐ ์์๊ฐ ์ฐจ๋ก๋๋ก ์ ๋ ฌ๋๊ฒ ๋๋ค.
ํ ์์ฑ ์๊ณ ๋ฆฌ์ฆ์ ์๊ฐ ๋ณต์ก๋๋ O(log N)์ด๊ณ , ์ ์ฒด ๋ฐ์ดํฐ์ ๊ฐฏ์๋ N๊ฐ ์ด๋ฏ๋ก ํ ์ ๋ ฌ์ ์ ์ฒด ์๊ฐ ๋ณต์ก๋๋ O(N*log N)์ด๋ผ๊ณ ํ ์ ์๋ค.
ํ์ด์ฌ
n = 9
heap = [7,6,5,8,3,5,1,9,6]
for i in range(1,n): #์ต๋ ํ ๊ตฌ์ฑ
c=i
while(c!=0):
root = int((c-1)/2)
if heap[root]<heap[c]:
tmp = heap[root]
heap[root] = heap[c]
heap[c] = tmp
print(heap)
c = root
print("*"*27)
print("*"*27)
for i in range(n-1,0,-1): #์์๋ฅผ ํ๊ฐ์ฉ ์ค์ด๋ฉด์ ํ ์ ๋ ฌ ์ํ
tmp = heap[0]
heap[0] = heap[i]
heap[i] = tmp
root = 0
c=1
while True:
c = 2*root+1
if c>i : break
if heap[c] < heap[c+1] and c < i-1:
c+=1
if heap[root] < heap [c] and c<i:
tmp = heap[root]
heap[root] = heap[c]
heap[c] = tmp
print(heap)
root = c
heap
์ด ๊ธ์ ๋๋๋น๋์ ์ค์ ์๊ณ ๋ฆฌ์ฆ ๊ฐ์ข (Algorithm Programming Tutorial)๋ฅผ ์ฐธ๊ณ ํด ์์ฑํ์์ต๋๋ค.
https://www.youtube.com/watch?v=qQ5iLNjpxSk&list=PLRx0vPvlEmdDHxCvAQS1_6XV4deOwfVrz