ex) 아래의 최대 힙에 새로운 요소 8을 삽입 해보자
ex) 아래의 최대 힙에서 최대값을 삭제해보자
package algorithmStudyPriorityQueue;
import java.util.Arrays;
import java.util.Comparator;
import java.util.NoSuchElementException;
public class Heap<E> {
private final Comparator<? super E> comparator;
private static final int DEFAULT_CAPACITY = 10; //최소 용량 크기
private int size; //요소 개수
private Object[] array; //요소를 담을 배열
//생성자
public Heap(){
this(null);
}
public Heap(Comparator<? super E> comparator){
this.array = new Object[DEFAULT_CAPACITY];
this.size = 0;
this.comparator = comparator;
}
public Heap(int capacity){
this(capacity,null);
}
public Heap(int capacity, Comparator<? super E> comparator){
this.array = new Object[capacity];
this.size =0;
this.comparator = comparator;
}
//받은 인덱스의 부모 노드 인덱스를 반환
private int getParent(int index){
return index/2;
}
//받은 인덱스의 왼족 노드 인덱스 반환
private int getLeftChild(int index){
return index*2;
}
//받은 인덱스의 오른족 자식 노드 인덱스 반환
private int getRightChild(int index){
return index*2+1;
}
//동적할당을 위한 resize method
private void resize(int newCapacity){
Object[] newArray = new Object[newCapacity];
for(int i=1;i<-size;i++){
newArray[i] = array[i];
}
this.array = null;
this.array = newArray;
}
public void add(E value){
if(size+1 == array.length){
resize(array.length*2);
}
siftUp(size+1,value);
size++;
}
private void siftUp(int idx, E target){
if(comparator != null){
siftUpComparator(idx, target,comparator);
}
else{
siftUpComparable(idx, target);
}
}
@SuppressWarnings("unchecked")
private void siftUpComparator(int idx, E target, Comparator<? super E> comp){
while(idx>1){
int parent = getParent(idx);
Object parentVal = array[parent];
if(comp.compare(target, (E)parentVal)>=0){
break;
}
array[idx] = parentVal;
idx = parent;
}
array[idx] = target;
}
@SuppressWarnings("unchecked")
private void siftUpComparable(int idx, E target){
Comparable<? super E> comp = (Comparable<? super E>) target;
while(idx > 1){
int parent = getParent(idx);
Object parentVal = array[parent];
if(comp.compareTo((E)parentVal)>=0){
break;
}
array[idx] = parentVal;
idx = parent;
}
array[idx]= comp;
}
@SuppressWarnings("unchecked")
public E remove(){
if(array[1] ==null){
throw new NoSuchElementException();
}
E result = (E) array[1];
E target = (E) array[size];
array[size] = null;
siftDown(1,target);
return result;
}
private void siftDown(int idx,E target){
if(comparator != null){
siftDownComparator(idx, target, comparator);
}
else{
siftDownComparable(idx, target);
}
}
@SuppressWarnings("unchecked")
private void siftDownComparator(int idx, E target, Comparator<? super E> comp){
array[idx] =null;
size--;
int parent = idx;
int child;
while((child=getLeftChild(parent))<=size){
int right = getRightChild(parent);
Object childVal = array[child];
if(right<=size&&comp.compare((E) childVal, (E) array[right])>0){
child = right;
childVal = array[child];
}
if(comp.compare(target,(E) childVal)<=0){
break;
}
array[parent] = childVal;
parent = child;
}
array[parent] = target;
if(array.length>DEFAULT_CAPACITY&& size<array.length/4){
resize(Math.max(DEFAULT_CAPACITY, array.length/2));
}
}
@SuppressWarnings("unchecked")
private void siftDownComparable(int idx, E target){
Comparable<? super E> comp = (Comparable<? super E>) target;
array[idx] = null;
size--;
int parent = idx;
int child;
while((child = getLeftChild(parent))<=size){
int right = getRightChild(parent);
Object childVal = array[child];
if(right <=size && ((Comparable<? super E>)childVal).compareTo((E)array[right])>0){
child =right;
childVal = array[child];
}
if(comp.compareTo((E) childVal)<=0){
break;
}
array[parent] = childVal;
parent = child;
}
array[parent] = comp;
if(array.length>DEFAULT_CAPACITY&& size<array.length/4){
resize(Math.max(DEFAULT_CAPACITY, array.length/2));
}
}
public int size() {
return this.size;
}
@SuppressWarnings("unchecked")
public E peek() {
if(array[1] == null) {
throw new NoSuchElementException();
}
return (E)array[1];
}
public boolean isEmpty() {
return size == 0;
}
public Object[] toArray() {
return Arrays.copyOf(array, size + 1);
}
}