Heap
- 우선 순위 큐 및 대기열을 만드는데 사용되어진다 (우선순위 큐를 구현할 때 가장 효율적이다)
- 완전 이진 트리의 일종이다(가질 수 있는 노드의 최댓값은 2^(k+1) - 1이다)
- 반정렬 상태를 유지한다
- 삽입/삭제는 O(logN)으로 매우 빠르다
- 배열의 자료구조로 저장된다
- 첫 index인 0은 사용되지 않는다
- Heap 정렬은 선택정렬의 원리를 가진다
종류
- 최대heap - 부모노드가 자식노드보다 크다
- 최소heap - 부모노드가 자식노드보다 작음
삽입
Heap에 데이터가 추가 되는 경우는 크게 2가지로 나뉜다.
1. Comparator가 nul이 아닐 때
2. Comparator가 null일 때
기본적으로 맨 밑 자식 노드에 값이 하나 추가되는 경우를 생각해보자.
1. 삽입된 노드와 부모 노드의 값을 비교한다.
2. 만약 부모 노드가 값이 더 크다면, 두 값을 변경한다
3. 변경한 위치에서의 부모노드와 해당 노드 값을 비교한다
4. 부모 노드의 값이 더 크면 값을 두 값을 변경한다.
5. 이와 같은 과정을 반복하다가 부모 노드의 값이 더 크지 않을 때 종료한다
위와 같은 과정(최소heap)을 상향 선별이라고 부른다
반대의 과정(최대 heap)을 하향 선별이라고 부른다
삭제
1. 최대 heap일 때
- 최대 값인 루트 노드를 삭제한다
- 마지막 index 노드를 루트 노드로 가져온다
- 자식 값이 더 크다면 교환한다
- 3의 과정 반복
코드예시)
int delete_max_heap(){
if (heapSize == 0) // 배열이 빈 경우
return 0;
int item = maxHeap[1]; // 루트 노드의 값을 저장한다.
maxHeap[1] = maxHeap[heapSize]; // 마지막 노드의 값을 루트 노드에 둔다.
maxHeap[heapSize--] = 0; // 힙 크기를 하나 줄이고 마지막 노드를 0으로 초기화한다.
for (int i=1; i*2<=heapSize;) {
// 마지막 노드가 왼쪽 노드와 오른쪽 노드보다 크면 반복문을 나간다.
if (maxHeap[i] > maxHeap[i*2] && maxHeap[i] > maxHeap[i*2+1]) {
break;
}
// 왼쪽 노드가 더 큰 경우, 왼쪽 노드와 마지막 노드를 swap
else if (maxHeap[i*2] > maxHeap[i*2+1]) {
swap(i, i*2);
i = i*2;
}
// 오른쪽 노드가 더 큰 경우, 오른쪽 노드와 마지막 노드를 swap
else {
swap(i, i*2+1);
i = i*2+1;
}
}
return item;
}
출처 : https://gmlwjd9405.github.io/2018/05/10/data-structure-heap.html
2. 최소 heap일 때
- 최소 값인 루트 노드를 삭제한다
- 마지막 index 노드를 루트 노드로 가져온다
- 자식 값이 더 작으면 교환한다
- 3의 과정을 반복한다
내가 직접 구현한 코드)
int delete_min_heap(){
if(heapSize==0){
return 0;
}
int rootnode = minheap[1];
//index 0 에는 아무 것도 대입하지 않기 때문이다
minheap[1] = minheap[heapSize];
minheap[heapSize--] = 0;
//마지막 노드가 0이 되고, heapSize가 감소된다
for(int i=1 ; i*2<=heapSize;){
//index마지막까지 가되, 자식 노드로 가면 i*2가 되어야함
if(minheap[i] < minheap[i*2] && minheap[i] < minheap[i*2+1]{
break;
}
else if (minheap[i*2] < minheap[i*2+1]){
swap(i, i*2+1);
i = i*2+1;
}
else {
swap(i, i*2);
i = i*2;
}
}
}
'Algorithm' 카테고리의 다른 글
recursive(1) (1) | 2023.07.27 |
---|---|
Greedy (0) | 2022.06.21 |
최소공배수와 최대공약수 (0) | 2022.06.19 |
스택으로 재귀함수를 비재귀적으로 구현하기 (0) | 2022.06.18 |
재귀 알고리즘 (0) | 2022.06.18 |