CS/알고리즘
힙 정렬
amungstudy
2024. 1. 4. 17:13
힙 정렬은 선택 정렬을 응용한 알고리즘이다. 힙을 사용하여 정렬한다.
여기서 '힙'은 '부못값이 자식값보다 항상 크다'라는 조건을 만족하는 완전이진트리이다.
모든 부모와 자식의 관계는 항상 부모값>= 자식값
힙정렬은 '가장 큰 값이 루트에 위치'하는 특징을 이용하는 정렬 알고리즘이다.
- 힙에서 가장 큰 값인 루트를 꺼냅니다
- 루트 이외의 부분을 힙으로 만듭니다
이 작업을 반복한다.
import java.util.Arrays;
public class HeapSort {
static void swap(int[] a, int idx1, int idx2){
int t = a[idx1];
a[idx1] = a[idx2];
a[idx2] = t;
}
public static void main(String[] args) {
System.out.println("힙정렬");
System.out.println("요솟수: 7 ");
int nx = 7;
int[] x = new int[]{6,4,3,7,1,9,8};
heapSort(x, nx);
System.out.println("오름차순으로 정렬했습니다");
for (int i = 0; i < nx; i++) {
System.out.println("x["+i+"]= "+x[i]);
}
}
static void heapSort(int[] a, int n) {
for(int i = (n-1) / 2; i >=0; i--) // a[i]~a[n-1]를 힙으로 만듦
downHeap(a, i, n-1);
for(int i = n-1; i>0; i--){
swap(a,0,i); // 가장 큰 요소와 아직 정렬되지 않은 마지막 요소를 교환
downHeap(a,0,i-1);
}
}
// a[left]~a[right]를 힙으로 만듦
/*
* 힙요소를 배열에 저장하면 생기는 관계
* 부모는 a[(i-1)/2]
* 왼쪽 자식은 a[i*2+1]
* 오른쪽 자식은 a[i*2+2]
* */
static void downHeap(int[] a, int left, int right) {
int temp = a[left]; //루트
int child; // 큰 값을 갖는 자식
int parent; // 부모
for(parent = left; parent < (right+1)/2; parent = child){
int cl = parent * 2 + 1; //왼쪽 자식
int cr = cl +1 ; // 오른쪽 자식
child = (cr <= right && a[cr]>a[cl])? cr: cl; // 큰 쪽을 자식에 대입
if(temp >= a[child])
break;
a[parent] = a[child];
}
a[parent] = temp;
}
}
힙 정렬의 시간복잡도는 O(n log n)