offer | peek | poll | size |
---|---|---|---|
O(log n) | O(1) | O(log n) | O(1) |
자바에서 Queue를 구현할 경우에 LinkedList를 사용하여 구현할 수 있고 Priority Queue를 사용하여 구현할 수 있다.
여기서 큐는 FIFO 방식의 자료구조이다.
그래프의 넓이 우선 탐색(BFS)에서 사용된다.
< LinkedList 구현 특징 >
< priorityQueue 구현 특징 >
package algorithmStudyPriorityQueue;
import Interface_form.Queue;
import java.security.PublicKey;
import java.util.Comparator;
import java.util.NoSuchElementException;
public class PriorityQueue<E> implements Queue<E> {
private final Comparator<? super E> comparator;
private static final int DEFAULT_CAPACITY = 10;
private int size;
private Object[] array;
//생성자
public PriorityQueue(){
this(null);
}
public PriorityQueue(Comparator<? super E> comparator){
this.array = new Object[DEFAULT_CAPACITY];
this.size =0;
this.comparator = comparator;
}
public PriorityQueue(int capacity){
this(capacity,null);
}
public PriorityQueue(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;
}
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;
}
@Override
public boolean offer(E value){
if(size+1 == array.length){
resize(array.length*2);
}
siftUp(size+1,value);
size++;
return true;
}
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;
}
@Override
public E poll(){
if(array[1] ==null){
return null;
}
return remove();
}
@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;
size--;
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;
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));
}
}
public int size() {
return this.size;
}
@Override
@SuppressWarnings("unchecked")
public E peek() {
if(array[1] == null) { // root 요소가 null일 경우 예외 던짐
throw new NoSuchElementException();
}
return (E)array[1];
}
public boolean isEmpty() {
return size == 0;
}
public boolean contains(Object value) {
for(int i = 1; i <= size; i++) {
if(array[i].equals(value)) {
return true;
}
}
return false;
}
public void clear() {
for(int i = 0; i < array.length; i++) {
array[i] = null;
}
size = 0;
}
}