Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 110
at HeapPriorityQueue.hasLeft(HeapPriorityQueue.java:168)
at HeapPriorityQueue.bubbleDown(HeapPriorityQueue.java:111)
at HeapPriorityQueue.removeMin(HeapPriorityQueue.java:73)
at a4tester.testRandomArray(a4tester.java:224)
at a4tester.stressTest(a4tester.java:237)
at a4tester.main(a4tester.java:283)
我一直试图找出Out of bounds异常的来源,这让我疯了!只有当我的HeapPriorityQueue通过下面的压力测试时才会出现。 当我的代码通过这个压力测试时,基本上会得到一个数组超出范围的异常:
public static boolean testRandomArray (int count) {
PriorityQueue q = createNewPriorityQueue(count);
System.out.println("Testing size: " + count);
Random r = new Random();
for ( int i = 0; i < count; i++ )
{
int val = r.nextInt(1000000);
q.insert (val);
}
int oldVal = -1;
while (!q.isEmpty() )
{
int val = (int)((Integer)q.removeMin()).intValue(); // or a bug
if ( oldVal > val )
return false;
oldVal = val;
}
return true;
}
这是我的计划:
public class HeapPriorityQueue implements PriorityQueue {
protected final static int DEFAULT_SIZE = 10000;
/* This array is where you will store the elements in the heap */
protected Comparable storage[];
/* Keep track of the current number of elements in the heap */
protected int currentSize;
/* You do not need to change this constructor */
public HeapPriorityQueue ()
{
this(DEFAULT_SIZE);
}
/* You do not need to change this constructor */
public HeapPriorityQueue(int size)
{
storage = new Comparable[size + 1];
currentSize = 0;
}
/*
* You need to change the implementation of every public method
* below this comment.
*
*/
public int size () {
return currentSize;
}
public boolean isEmpty () {
if(size() == 0)
return true;
return false;
}
public Comparable removeMin () throws HeapEmptyException {
if(isEmpty())
throw new HeapEmptyException();
Comparable returnValue = storage[1];
storage[1] = storage[currentSize];
storage[currentSize] = null;
currentSize--;
bubbleDown();
return returnValue;
}
public void insert ( Comparable k ) throws HeapFullException {
if(currentSize >= storage.length - 1)
throw new HeapFullException();
currentSize++;
storage[currentSize] = k;
bubbleUp();
}
/* Your instructor's solution used the following helper methods
*
* You do not need to use the same methods, but you may want to.
*/
/*
* A new value has just been added to the bottom of the heap
* "bubble up" until it is in the correct position
*/
private void bubbleUp () {
int index = currentSize;
while(parent(index) != 0 && storage[parent(index)].compareTo(storage[index]) > 0) {
swapElement(index, parent(index));
index = parent(index);
}
}
/*
* Because of a removeMin operation, a value from the bottom
* of the heap has been moved to the root.
*
* "bubble down" until it is in the right position
*/
private void bubbleDown() {
int index = 1;
while (hasLeft(index)) {
int sc = leftChild(index);
if (hasRight(index) && storage[leftChild(index)].compareTo(storage[rightChild(index)]) > 0) {
sc = rightChild(index);
}
if (storage[index].compareTo(storage[sc]) > 0) {
swapElement(index, sc);
}
else{
}
index = sc;
}
}
/*
* Swap the element at position p1 in the array with the element at
* position p2
*/
private void swapElement ( int p1, int p2 ) {
Comparable temp = storage[p1];
storage[p1] = storage[p2];
storage[p2] = temp;
}
/*
* Return the index of the parent of the node at pos
*/
private int parent ( int pos )
{
return (pos/2); // replace this with working code
}
/*
* Return the index of the left child of the node at pos
*/
private int leftChild ( int pos )
{
return (pos*2); // replace this with working code
}
/*
* Return the index of the right child of the node at pos
*/
private int rightChild ( int pos )
{
return (pos * 2)+1; // replace this with working code
}
/*
* Given the current number of elements in the heap, does the
* node at pos have a left child?
*
* Note that all internal nodes have at least a left child.
*
*/
private boolean hasLeft ( int pos )
{
if(storage[leftChild(pos)] != null)
return true;
return false; // replace this with working code
}
/*
* Given the current number of elements in the heap, does the
* node at pos have a right child?
*/
private boolean hasRight ( int pos ) {
if(storage[rightChild(pos)] != null)
return true;
return false; // replace this with working code
}
}
答案 0 :(得分:2)
有一些可能存在问题的事情:
private boolean hasLeft ( int pos )
{
if(storage[leftChild(pos)] != null)
return true;
return false; // replace this with working code
}
应改为:
private boolean hasLeft ( int pos )
{
if (storage.length > leftChild(pos) && storage[leftChild(pos)] != null)
return true;
return false; // replace this with working code
}
因为您可能会在原始代码中超出范围。同样的逻辑适用于hasRight()
。此外,您还尝试访问storage
,但是您从未查看其长度,即您有storage[1]
,但不保证您没有{39} ; t传递0给你的构造函数。希望有所帮助。