๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

์•Œ๊ณ ๋ฆฌ์ฆ˜

์•Œ๊ณ ๋ฆฌ์ฆ˜ [Algorithm] - ํž™ ์ •๋ ฌ Heap Sort(6) (C,Python)

ํž™์ •๋ ฌ

์ด๋ฒˆ์—๋Š” ํž™ ์ •๋ ฌ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž. ํž™์ •๋ ฌ์ด๋ž€ ํž™ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•˜๋Š” ์ •๋ ฌ๋ฐฉ๋ฒ•์ด๋‹ค. ์ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„  ๋จผ์ € ํž™(Heap)๊ตฌ์กฐ๋ฅผ ์•Œ์•„์•ผํ•˜๊ณ , ํž™์„ ์•Œ๊ธฐ ์ด์ „์—๋Š” ์ด์ง„ ํŠธ๋ฆฌ(Binary Tree)์— ๋Œ€ํ•ด ์•Œ์•„์•ผ ํ•œ๋‹ค. 

 ์ถœ์ฒ˜ : https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%ED%8A%B8%EB%A6%AC

์ด์ง„ ํŠธ๋ฆฌ(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 

 

 

728x90