/*
* Copyright 2013 Websquared, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.fastcatsearch.ir.io;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author sangwook.song
*
*/
public class FixedMinHeap<T extends Comparable<T>> {
protected static Logger logger = LoggerFactory.getLogger(FixedMinHeap.class);
protected Object[] heap;
protected int maxsize;
protected int size;
public FixedMinHeap(int maxsize){
this.maxsize = maxsize;
heap = new Object[maxsize + 1];
}
//원소갯수
public int size(){
return size;
}
public boolean push(T e){
if (size < maxsize) {
size++;
heap[size] = e;
upHeap();
// logger.debug("PUSHBACK = "+e);
return true;
}
return false;
// logger.debug("TOP = "+heap[1]);
}
public T pop(){
if (size > 0) {
Object top = heap[1];
heap[1] = heap[size];
heap[size] = null;
size--;
heapify();
return (T) top;
}
return null;
}
public T peek(){
if (size > 0)
return (T) heap[1];
return null;
}
public void print(){
for (int i = 0; i < size; i++) {
logger.info("{}", heap[i + 1]);
}
}
private void upHeap() {
int idx = size;
Object node = heap[idx];
int parent = idx >> 1;
// while ((parent > 0) && ((T)node).compareTo((T)heap[parent]) < 0) {
while ((parent > 0) && compareTo((T)node ,(T)heap[parent]) < 0) {
heap[idx] = heap[parent];
idx = parent;
parent = parent >> 1;
}
heap[idx] = node;
}
//
// 정책에 따라 compareTo 를 상속하여 변경할수 있다.
//
protected int compareTo(T a, T b){
return a.compareTo(b);
}
public void heapify(){
int child = -1;
int idx = 1;
while(idx <= size){
int left = idx * 2;
int right = left + 1;
if(left <= size){
if(right <= size){
if(compareTo((T)heap[left], (T)heap[right]) < 0)
child = left;
else
child = right;
}else{
//if there is no right el.
child = left;
}
}else{
//no children
break;
}
//현재 노드와 child와 비교해서 swap한다.
if(compareTo((T)heap[child], (T)heap[idx]) < 0){
Object temp = heap[child];
heap[child] = heap[idx];
heap[idx] = temp;
idx = child;
}else{
//같거나 정렬되어 있으면 child를 확인하지 않는다.
break;
}
}
}
}