Skip to content

Commit 0becda1

Browse files
authored
Merge pull request #34 from Data-Structure-Study/yoonexample
우선순위를 직접 지정하는 배열기반의 힙 클래스 구현
2 parents 11a65f6 + c33aea9 commit 0becda1

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package heap;
2+
3+
public class ArraySimpleHeap<E> implements SimpleHeap<E> {
4+
5+
private static final int INITIAL_CAPACITY = 100 + 1;
6+
7+
private int numOfData;
8+
private HeapElement<E>[] heapArr;
9+
10+
public ArraySimpleHeap() {
11+
this.heapArr = new HeapElement[INITIAL_CAPACITY];
12+
}
13+
14+
@Override
15+
public boolean isEmpty() {
16+
return numOfData == 0;
17+
}
18+
19+
@Override
20+
public void insert(E data, int priority) {
21+
int index = numOfData + 1;
22+
HeapElement<E> nextElement = new HeapElement<>(data, priority);
23+
24+
while (index != 1) {
25+
int parentIndex = getParentIndex(index);
26+
27+
// 부모 노드와 비교했을 때, 부모노드보다 우선순위가 높다면 서로의 위치를 바꾼다.
28+
if (priority < this.heapArr[parentIndex].priority) {
29+
this.heapArr[index] = this.heapArr[parentIndex];
30+
index = parentIndex;
31+
} else {
32+
break;
33+
}
34+
}
35+
36+
this.heapArr[index] = nextElement;
37+
this.numOfData += 1;
38+
}
39+
40+
@Override
41+
public E delete() {
42+
int rootIndex = 1;
43+
E retData = this.heapArr[rootIndex].data; // 루트노드에 존재하던 데이터
44+
HeapElement<E> lastElement = this.heapArr[this.numOfData]; // 마지막 노드
45+
46+
int parentIndex = rootIndex; // 루트로 옮기는 것을 의미
47+
int childIndex = getHighPrioirtyChildIndex(parentIndex); // 더 우선순위인 자식노드
48+
49+
while (childIndex > 0) { // 부모노드가 단말노드가 아니라면
50+
if (lastElement.priority <= this.heapArr[childIndex].priority) { // 마지막 노드가 우선순위가 높다면
51+
break;
52+
}
53+
this.heapArr[parentIndex] = this.heapArr[childIndex]; // 자식 노드와 부모노드의 위치를 변경
54+
parentIndex = childIndex;
55+
childIndex = getHighPrioirtyChildIndex(parentIndex);
56+
}
57+
58+
this.heapArr[parentIndex] = lastElement; // 마지막에 위치했던 노드를 한 번에 옮긴다.
59+
this.numOfData -= 1;
60+
return retData;
61+
}
62+
63+
/**
64+
* 부모 노드의 인덱스 반환 요청
65+
*
66+
* @param currentIndex 현재 자식 노드의 인덱스
67+
* @return 부모노드의 인덱스
68+
*/
69+
private int getParentIndex(int currentIndex) {
70+
return currentIndex / 2;
71+
}
72+
73+
/**
74+
* 왼쪽 자식 노드의 인덱스 반환 요청
75+
*
76+
* @param parentIndex 부모 노드의 인덱스
77+
* @return 왼쪽 자식 노드의 인덱스
78+
*/
79+
private int getLeftChildIndex(int parentIndex) {
80+
return parentIndex * 2;
81+
}
82+
83+
/**
84+
* 오른쪽 자식 노드의 인덱스 반환 요청
85+
*
86+
* @param parentIndex 부모 노드의 인덱스
87+
* @return 오른쪽 자식 노드의 인덱스
88+
*/
89+
private int getRightChildIndex(int parentIndex) {
90+
return parentIndex * 2 + 1;
91+
}
92+
93+
/**
94+
* 두 개의 자식 노드 중 우선순위가 더 높은 자식의 인덱스 반환 요청
95+
*
96+
* @param currentIndex 판단의 기준이 되는 노드
97+
* @return 우선순위가 더 높은 자식 노드의 인덱스
98+
*/
99+
private int getHighPrioirtyChildIndex(int currentIndex) {
100+
int leftChildIndex = this.getLeftChildIndex(currentIndex);
101+
if (leftChildIndex > this.numOfData) { // 존재하지 않는 노드라면
102+
return 0;
103+
}
104+
if (leftChildIndex == this.numOfData) { // 왼쪽노드가 마지막 노드라면
105+
return leftChildIndex;
106+
}
107+
108+
int rightChildIndex = this.getRightChildIndex(currentIndex);
109+
int leftChildNodePriority = this.heapArr[leftChildIndex].priority;
110+
int rightChildNodePriority = this.heapArr[rightChildIndex].priority;
111+
112+
// 우선순위는 낮은것이 더 우위이므로 왼쪽노드가 더 우선순위가 낮다면
113+
if (leftChildNodePriority > rightChildNodePriority) {
114+
return rightChildIndex;
115+
}
116+
return leftChildIndex;
117+
}
118+
119+
private static class HeapElement<T> {
120+
121+
private final T data;
122+
private final int priority;
123+
124+
public HeapElement(T data, int priority) {
125+
this.data = data;
126+
this.priority = priority;
127+
}
128+
}
129+
}

0 commit comments

Comments
 (0)