Arrays in Java are zero-indexed. You're setting your loop upper bound (n
) to be A.length
, then doing a less than or equal to comparison against it, so it will always check for one too many elements.
if(left <= n && A[left] > A[i]){
Should be
if(left < n && A[left] > A[i]){
And
if(right <= n && A[right] > A[largest]){
Should be
if(right < n && A[right] > A[largest]){
You're also performing a dodgy operation to initialise right
. createHeap()
sets i
to be equal to n/2
(which is potentially a bug in itself). You then pass this value through to maxHeap
in the form of the parameter i
. Then you're doing this:
int right = 2*i+1;
What happens here when i
is say, 2?
In order for i
to be 2
, A.length
must be 5
or 6
(because createHeap
sets n
to be A.length - 1
, so (5 - 1) / 2 = 4
as does (6 - 1) / 2
). When this trickles through to maxheap
, 2 * i + 1
takes you up to 5
, which is out of bounds of A
(it may be the length, but if that's the case, then 4
is the highest index, not 5
).
So, this is the situation when A.length = 5
:
if(right <= n && A[right] > A[largest]) {
^ 5 ^ 5 ^ ArrayIndexOutOfBoundsException thrown here.
right <= n
evaluates to true
, because 5
does indeed equal 5
, so A[right]
is evaluated, and promptly fails with your exception. A simple less than check on right < n
would prevent this, as 5
is not less than 5
, so the first condition evaluates to false
, thereby ensuring that A[right]
would not get evaluated at all.
In short - this doesn't work for an odd length array.
Remember: The .length
property of an array tells you how many elements that array can contain, not the index of the last element.