본문 바로가기
알고리즘

힙 정렬

by 휘성티비 2024. 2. 18.

 

힙 정렬은 힙 트리 구조를 이용하는 정렬 방법이다.

 

이진트리

먼저 이진트리란 모든 노드가 두개의 자식노드를 가지는 것을 말한다. 트리라는 말 처럼 가지가 뻗어있는 형태다.

 

완전 이진 트리란 루트 노드부터 시작해서 자식 노드가 왼쪽 자식 노드, 오른쪽 자식 노드로 차근차근 들어가는 구조의 이진트리이다.

 

힙(Heap)이란 최솟값이나 최댓값을 빠르게 찾아내기 위해 완전 이진 트리를 기반으로 하는 트리이다.

>

최대 힙: '부모 노드'가 '자식 노드'보다 큰 힙을 말한다.

 

힙 정렬을 하기 위해서는 정해진 데이터가 힙 구조를 가지도록 만들어야 한다.

 

힙 정렬을 수행하기 위해서는 힙 생성 알고리즘을 사용한다. 이는 특정한 '하나의 노드'에 대해서 수행하는 것이다. 또한 해당 하나의 노드를 제외하고는 최대 힙이 구성되어 있는 상태라고 가정을 한다는 특징이 있다. 특정한 하나의 노드에 대해 최대 힙 정렬을 수행해주면 전체 트리가 최대 힙 구조로 형성된다.

 

힙 생성 알고리즘

힙 생성 알고리즘은 특정한 노드의 두 자식 중에서 더 큰 자식과 자신의 위치를 바꾸는 알고리즘이다. 또한 위치를 바꾼 뒤에도 여전히 자식이 존내하는 경우 자식 중에서 더 큰 자식과 자신의 위치를 바꾸어야 한다.

 

힙 생성 알고리즘의 시간 복잡도

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

데이터의 갯수가 1024개라면 10번 정도만 내려가면 된다.

 

모든 노드에 힙 정렬을 하면 N*(logN)이다.

 

#include<bits/stdc++.h>
using namespace std;
int number = 9;
int heap[9] = {7,6,5,8,3,5,9,1,6}; 
int main()
{
	for(int i=1; i<number; i++){
		int c=i;
		do {
			int root = (c-1)/2;
			if(heap[root] < heap[c]){
				int temp = heap[root];
				heap[root] = heap[c];
				heap[c] = temp;
			}
			c = root;	
		}while(c!=0);
	}
	//크기를 줄여가며 반복적으로 힙을 구성  
	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[0] = heap[c];
				heap[c] = temp;
			} 
			root = c;
		} while(c<i);
	}
	for(int i=0; i<number; i++)
		cout << heap[i] << ' ';
}

'알고리즘' 카테고리의 다른 글

버블 정렬  (0) 2024.02.18
삽입 정  (0) 2024.02.18
퀵 정렬  (0) 2024.02.18
병합 정렬  (0) 2024.02.18
계수 정렬  (0) 2024.02.18