/** * ScoreQueue - A simple max heap for storing high scores and names * @author Yama H * @version 1.0 */ public class ScoreQueue { /** * Default value for the initial capacity of the queue */ public static final int DEFAULT_INIT_CAPACITY = 16; private int capacity; // current capacity private int index; // index of first free element private Score[] scoreArray; /** * Constructor for objects of class ScoreQueue * @param initCapacity initial capacity of array */ public ScoreQueue(int initCapacity) { scoreArray = new Score[initCapacity]; capacity = initCapacity; index = 0; } private ScoreQueue(Score[] scores, int capacity, int index) { scoreArray = scores; this.capacity = capacity; this.index = index; } /** * Constructor for objects of class ScoreQueue * Initial capacity defaults to 16 */ public ScoreQueue() { scoreArray = new Score[DEFAULT_INIT_CAPACITY]; capacity = DEFAULT_INIT_CAPACITY; index = 0; } private void grow() { Score[] tmp = new Score[2*capacity]; for(int i=0; i= capacity-1) grow(); if(isEmpty()) scoreArray[index++] = s; else { scoreArray[index] = s; trickleUp(index++); } } private void trickleUp(int k) { if(k != 0) { if(scoreArray[k].getScoreInt() > (scoreArray[parent(k)].getScoreInt())) { Score tmp = scoreArray[k]; scoreArray[k] = scoreArray[parent(k)]; scoreArray[parent(k)] = tmp; trickleUp(parent(k)); } } } protected int parent(int k) { return (k - 1) / 2; } protected int left(int k) { return 2 * k + 1; } protected int right(int k) { return 2 * (k + 1); } /** * Removes and retrieves the largest element (the score with the highest integer value) in the heap * @return the highest score */ public Score poll() { if(isEmpty()) throw new java.util.NoSuchElementException(); else if(index == 1) { Score ret = scoreArray[0]; scoreArray[0] = null; index = 0; return ret; } else { Score ret = scoreArray[0]; scoreArray[0] = scoreArray[--index]; scoreArray[index] = null; trickleDown(0); return ret; } } /** * Retrieves but does not return the largest element in the heap * @return the highest score */ public Score peek() { return scoreArray[0]; } private void trickleDown(int k) { if(left(k) < index && right(k) < index) { if(scoreArray[left(k)].getScoreInt() >= scoreArray[right(k)].getScoreInt()) { if(scoreArray[left(k)].getScoreInt() > scoreArray[k].getScoreInt()) { Score tmp = scoreArray[k]; scoreArray[k] = scoreArray[left(k)]; scoreArray[left(k)] = tmp; trickleDown(left(k)); } } else if(scoreArray[right(k)].getScoreInt() > scoreArray[left(k)].getScoreInt()) { if(scoreArray[right(k)].getScoreInt() > scoreArray[k].getScoreInt()) { Score tmp = scoreArray[k]; scoreArray[k] = scoreArray[right(k)]; scoreArray[right(k)] = tmp; trickleDown(right(k)); } } } else if(left(k) < index) { if(scoreArray[left(k)].getScoreInt() > scoreArray[k].getScoreInt()) { Score tmp = scoreArray[k]; scoreArray[k] = scoreArray[left(k)]; scoreArray[left(k)] = tmp; trickleDown(left(k)); } } } /** * Returns the size of the heap expressed as an integer * @return the size of the heap */ public int size() { return index; } /** * Determines whether or not the heap is empty * @return whether or not the heap is empty */ public boolean isEmpty() { if(scoreArray[0] == null && index == 0) { return true; } else if(scoreArray[0] == null || index == 0) { throw new InternalError(); } else return false; } /** * Converts this heap to an array * @return an array depiction of the heap */ public Score[] toArray() { Score[] ret = new Score[capacity]; for(int i=0; i