c & c++/algorithm

힙 정렬(Heap)

일상코더 2022. 7. 11. 22:49

Goal

      - Heap Sort 에 대해 설명할 수 있다.

      - Heap Sort 과정에 대해 설명할 수 있다.

      - Heap Sort를 구현할 수 있다.

      - Heap Sort의 시간 복잡도를 계산 할 수 있다.


1. Heap Sort Summary

 

      - 힙 트리 구조(Heap Tree Structure)를 이용하는 정렬방법

      - 최솟값과 최댓값을 빠르게 찾아내기 위해 완전 이진 트리를 기반으로 하는 트리  

      - 이진 트리에 대한 이해 필요(완전 이진 트리)

      - 최대힙  = '부모 노드'가 '자식 노드' 보다 큰 힙

      - 힙 생성 알고리즘 (Heapify Algorithm) 을 사용해야함

                        - 힙 생성 알고리즘 = 특정한 노드의 두 자식 중에서 더큰 자식과 자신의 위치를 바꾸는 알고리즘

 


2. Heap Sort Processing

 

    - 정렬할 N개의 원소로 최대  구성

    - 최대 힙의 루트 노드(가장 큰 원소)와 마지막 원소 위치 교환

    - 새 루트 노드에 대해 최대  구성

    - 원소 개수만큼 2와 3을 반복 수행

 


3. Heap Sort Coding

 

//heap 정렬 이진트리 완전 이진 트리 구조
#include <stdio.h>

int number = 10;
int heap[10] = { 1, 4, 5, 6, 10, 9, 7, 8, 3, 2};
int main(void)
{
	int i , temp, c, root;
	//전체 트리 구조를 최대 힙 구조로 바꾼다
	 
	for(i = 1; i < number; i++) // i가 0이면 root 값을 나타나게 됨으로 1부터 시작 
	{
		c = i; // root와 비교하기위해 1부터 시작 
		do{
			root = ( c - 1) / 2; // c = 1부터 이기때문에 root 는 0부터 시작 
			if(heap[root] < heap[c])
			{
				temp = heap[root];
				heap[root] = heap[c];
				heap[c] = temp;
 			}
 			c = root;
		}while( c != 0); //c가 0이 될때까지 반복 
	}
	//크기를 줄여가며 반복적으로 힙을 구성
	for(i = number -1; i >= 0; i--)
	{
		temp = heap[0];
		heap[0] = heap[i];
		heap[i] = temp;
		root = 0;
		c = 1;
		do{
			c = 2 * root + 1;  
			//자식 중에 더큰 값을 찾기
			if(heap[c] < heap[c+1] && c < i - 1)
			{
				c++;
			}
			//루트보다 자식이 더 크다면 교환
			if(heap[root] < heap[c] && c < i)
			{
				temp = heap[root];
				heap[root] = heap[c];
				heap[c] = temp;
			}
			root = c;		
		}while(c < i);
	}
	for(i = 0 ; i < number; i++)
	{
		printf("%d ", heap[i]);
	}
	return 0;
 }

4. Heap 정렬 시간 복잡도

 

            - 한 번 자식 노드로 내려갈 때마다 노드의 갯수가 2배씩 증가한다는 점에서 O(log N)

            - 병합 정렬, 퀵 정렬 만큼 빠른 정렬 알고리즘