profile-img
The merit of an action lies in finishing it to the end.
slide-image

Heap์˜ ๊ฐœ๋…

ํž™์€ ํŠธ๋ฆฌ์˜ ์ผ์ข…์ธ๋ฐ, "complete tree"์ด๊ฑฐ๋‚˜ "nearly complete tree"์ด์–ด์•ผ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ข…๋ฅ˜๋กœ ๋‚˜๋‰œ๋‹ค.

max-heap์˜ ๊ฒฝ์šฐ ๊ฐ ๋…ธ๋“œ์˜ key ๊ฐ’์ด ์ž์‹ ๋…ธ๋“œ๋“ค์˜ key ๊ฐ’๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™๊ณ , min-heap์˜ ๊ฒฝ์šฐ ๊ฐ ๋…ธ๋“œ์˜ key ๊ฐ’์€ ์ž์‹ ๋…ธ๋“œ๋“ค์˜ key ๊ฐ’๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์•„์•ผ ํ•œ๋‹ค.

 

 

max-heap & min-heap

Heap์˜ ํŠน์„ฑ

max-heap์„ ๊ธฐ์ค€์œผ๋กœ ์‚ดํŽด๋ณด์ž. ํž™์˜ root๋Š” ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ํฐ ๊ฐ’์„ ๊ฐ–๊ณ  ์žˆ์œผ๋ฉฐ, root์˜ ์™ผ์ชฝ/์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋„ ๊ฐ™์€ ํŠน์„ฑ์„ ์œ ์ง€ํ•œ๋‹ค. ๋งŒ์•ฝ min-heap์ด๋ผ๋ฉด ํž™์˜ root๊ฐ€ ํŠธ๋ฆฌ์—์„œ ๊ฐ€์žฅ ์ž‘์€ ๊ฐ’์„ ๊ฐ–๊ฒŒ ๋œ๋‹ค.

๊ตฌํ˜„์€ ์ฃผ๋กœ linked list๋ณด๋‹ค๋Š” array๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

array๋กœ ๊ตฌํ˜„ํ•œ heap

๋…ธ๋“œ์™€ ์ž์‹ ๊ฐ„์˜ ๊ด€๊ณ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

index๊ฐ€ i์ธ ๋…ธ๋“œ๋ฅผ ์ƒ๊ฐํ•ด๋ณธ๋‹ค๋ฉด,

    • i๋ฒˆ์งธ ๋…ธ๋“œ ์™ผ์ชฝ ์ž์‹: 2i+1
    • i๋ฒˆ์งธ ๋…ธ๋“œ ์˜ค๋ฅธ์ชฝ ์ž์‹: 2i+2
    • i๋ฒˆ์งธ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ ๋…ธ๋“œ: floor((i-2)/2)
    • j๋ฒˆ์งธ ๋…ธ๋“œ๊ฐ€ ์™ผ์ชฝ ์ž์‹์ด๋ฉด, ์˜ค๋ฅธ์ชฝ ์ž์‹์€ j+1

 

Heap์˜ ์—ฐ์‚ฐ

Heap์—์„œ ์ž๋ฃŒ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ˆœํšŒ, ๊ฒ€์ƒ‰, ์ถœ๋ ฅ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ๋„ ์ž‘๋™ํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค๋งŒ ํž™์€ ์œ„์—์„œ ์–ธ๊ธ‰ํ•œ, root์˜ key ๊ฐ’์ด ๊ฐ€์žฅ ํฌ๊ฑฐ๋‚˜ (max-heap) ์ž‘์•„์•ผ (min-heap) ํ•˜๊ณ  ๊ทธ ํŠน์„ฑ์ด ๋ชจ๋“  ์„œ๋ธŒํŠธ๋ฆฌ์— ๋Œ€ํ•ด์„œ๋„ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋˜์–ด์•ผ ํ•˜๋ฉฐ, ์ •์˜ํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ (nearly) complete tree๋ผ๋Š” ํŠน์„ฑ๋„ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

๋งŒ์•ฝ ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋ฅผ ํ•œ ํ›„ ๊ทธ๋ƒฅ ๊ฐ€๋งŒํžˆ ๋‘”๋‹ค๋ฉด ํž™์˜ ์ •์˜๋ฅผ ๋งŒ์กฑํ•˜์ง€ ๋ชปํ•  ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” Reheap up / Reheap down ์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•ด์„œ heap์˜ ๋ชจ์–‘์„ ์œ ์ง€ํ•˜๋„๋ก ํ•œ๋‹ค.

์ˆ˜๋„์ฝ”๋“œ์˜ ๊ฒฝ์šฐ, ์ˆœํšŒ, ๊ฒ€์ƒ‰, ์ถœ๋ ฅ ์ž์ฒด๋Š” ๊ธฐ์กด ํŠธ๋ฆฌ์—์„œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๋ฏ€๋กœ ๊ฑด๋„ˆ๋›ฐ๊ณ , ์‚ฝ์ž… ๋ฐ ์‚ญ์ œ์˜ ๊ฒฝ์šฐ๋Š” ๊ฐ๊ฐ ํ•จ์ˆ˜์˜ ๋’ท๋ถ€๋ถ„์—์„œ Reheap up, Reheap downํ•จ์ˆ˜๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๊ฑด๋„ˆ๋›ฐ๋„๋ก ํ•˜๊ฒ ๋‹ค. ์—ฌ๊ธฐ์—์„œ๋Š” Reheap Up ๋ฐ Reheap Down์— ๋Œ€ํ•ด์„œ๋งŒ ์†Œ๊ฐœํ•˜๋„๋ก ํ•˜๊ฒ ๋‹ค.

 

Reheap Up

์‚ฝ์ž… ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ๊ฐ™์ด ๋ถˆ๋Ÿฌ์™€์•ผ ํ•˜๋Š” ํ•จ์ˆ˜๋กœ ๊ฐ€์žฅ ๋งˆ์ง€๋ง‰์— ์‚ฝ์ž…๋œ ์š”์†Œ๋ฅผ ์œ„์ชฝ์œผ๋กœ ์ด๋™์‹œํ‚ค๋ฉด์„œ ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜์— ๊ฐˆ ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. ์‚ฝ์ž… ์ž์ฒด๋Š” ๊ฐ€์žฅ ์ฒซ ๋ฒˆ์งธ ๋นˆ leaf node์— ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— heap์˜ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” node๋ฅผ ์ด๋™์‹œ์ผœ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

reheap up์ด ์ด๋ฃจ์–ด์ง€๋Š” ๋‹จ๊ณ„

์‚ฝ์ž…๋œ ๋…ธ๋“œ์˜ ๋ถ€๋ชจ ๋…ธ๋“œ์™€ key ๊ฐ’์„ ๋น„๊ตํ•˜์—ฌ, ๋งŒ์•ฝ ์‚ฝ์ž…๋œ ๋…ธ๋“œ๊ฐ€ ๋ถ€๋ชจ ๋…ธ๋“œ์˜ key ๊ฐ’๋ณด๋‹ค ํฌ๋ฉด ์„œ๋กœ ์œ„์น˜๋ฅผ ๊ตํ™˜ํ•œ๋‹ค. ์ด ๊ณผ์ •์„ ๊ณ„์† ๋ฐ˜๋ณตํ•˜์—ฌ heap์˜ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€์‹œํ‚จ๋‹ค.

์ˆ˜๋„์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

void reheapUp (HEAP *heap, NODE *newNode) {
	if (newNode != root) {
		parent = parent->newNode;
		if (newNode->key > parent->key) {
			swap(newNode, parent);
			reheapUp(heap,parent);
		}
	}
}

 

Reheap Down

heap์€ nearly complete tree์ด๋ฏ€๋กœ root์„ ๋ฐ”๋กœ ์‚ญ์ œํ•˜๊ฒŒ ๋˜๋ฉด, heap์˜ ๊ตฌ์กฐ๊ฐ€ ์œ ์ง€๋˜์ง€ ๋ชปํ•œ๋‹ค. ๋”ฐ๋ผ์„œ last tree node์˜ ๊ฐ’์„ root๋กœ ์˜ฎ๊ธด ํ›„, root๋ฅผ ์•„๋ž˜๋กœ ์ด๋™์‹œ์ผœ์„œ heap์˜ ๋ฐฐ์—ด ํŠน์„ฑ(heap-ordering property)์ด ์ถฉ์กฑ๋˜๋„๋ก ์œ„์น˜๋ฅผ ๋ณ€๊ฒฝํ•ด์•ผํ•œ๋‹ค.

root ๋…ธ๋“œ๋ฅผ ์‚ญ์ œํ•  ๋•Œ, ๊ทธ๋ƒฅ ์‚ญ์ œํ•˜๊ฒŒ ๋˜๋ฉด heap์˜ ๊ตฌ์กฐ๊ฐ€ ๋ถ•๊ดด๋˜๋ฏ€๋กœ, ์ž์‹ ๋…ธ๋“œ ์ค‘ ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ์™€ ๊ฐ’์„ ๊ตํ™˜ํ•ด๊ฐ€๋ฉฐ heap ๊ตฌ์กฐ์˜ ๋งˆ์ง€๋ง‰ ๋…ธ๋“œ๋กœ ์ด๋™์‹œํ‚จ ํ›„ ์‚ญ์ œํ•œ๋‹ค.

์ˆ˜๋„์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

void reheapDown (HEAP *heap, NODE *root, int last) {
	if (root->left) {
		int leftKey = root->left->key;
		if (root->right) {
			int rightKey = root->right->key;
		}
		else {
			int rightKey = NULL;
		}
	}
	if (leftKey > rightKey) {
		largeSubtree = root->left;
	}
	else {
		largeSubtree = root->right;
	}
	if (root->key < largeSubtree->key) {
		swap(root, largeSubtree);
		reheapDown(heap, largeSubtree, last);
	}
}
1