Я пытаюсь написать массив на основе реализации алгоритма сортировки кучи. Цель состоит в том, чтобы построить кучу в массиве, а затем удалить минимальный элемент в корневом массиве и вернуть его в исходный массив. Это выполняется до тех пор, пока массив не будет отсортирован.Индекс массива вне границ в массиве на основе массива
Замена корня должна исходить из последнего элемента массива, который затем удаляется и помещается в корень. Новый корневой элемент по необходимости заменяется одним своим дочерним элементом. Это продолжается до тех пор, пока оно не находится в правильном месте.
Однако я продолжаю получать исключение индекса массива из-за пределов, и я просто не могу найти проблему. Я слишком долго работал над этим.
Я был бы очень признателен, если бы кто-то мог мне помочь.
public class ImprovedHeapSort<T>
{
/**
* @param unsortedArr Array to be sorted
* @return sortedArr The sorted array
*
* Static method which is an improved version of the HeapSort algorithm. The array
* is used to create a sorted array, which is treated as a minheap.
*
* The root is at index 0 and the last element is at index length-1.
* Each element is compared to its children, which are at positions 2n+1 and 2(n+1).
* Swapping and comparison continues until the root is reached.
*
*
*/
public static <T extends Comparable<T>> T[] HeapSort (T[] unsortedArr)
{
/*
* Throw exception if array is empty.
*/
if (unsortedArr[0] == null)
{
throw new EmptyCollectionException("Array");
}
/*
* If array only contains one element.
*/
if (unsortedArr.length == 1)
{
return unsortedArr;
}
T[] heapArr = Arrays.copyOf(unsortedArr, unsortedArr.length);
for(int i = 0; i < unsortedArr.length; i++)
{
heapArr[i] = unsortedArr[i];
/*
* Swapping to put element in appropriate location, if necessary.
*/
int cur = i;
T temp = heapArr[i];
/*
* Swapping until root isn't reached and the element being added
* would no longer be less than its parent.
*/
while(cur > 0 && temp.compareTo(heapArr[(cur-1)/2]) < 0)
{
heapArr[cur] = heapArr[(cur-1)/2]; //Swap cur with parent
cur = (cur-1)/2; //Move up to parent
}
heapArr[cur] = temp; //Insert at appropriate spot.
}
/*
* Remove the root element from the heap array and add it to unsortedArr
*
*/
for (int y = 0; y < unsortedArr.length; y++)
{
int count = heapArr.length - (y+1); //Count decreased after every pass.
T rootElem = heapArr[0]; //Store root
heapArr[0] = heapArr[heapArr.length- (y+1)]; //Set root to last element.
unsortedArr[y] = rootElem; //Add root to unsortedArr
int node = 0;
int left = 1;
int right = 2;
int next;
if ((heapArr[left] == null) && (heapArr[right] == null))
next = count-1;
else if (heapArr[right] == null)
next = left;
else if (heapArr[left].compareTo(heapArr[right]) < 0)
next = left;
else
next = right;
T temp = heapArr[node];
/*
* Swap until appropriate location is found. Least child is shifted up.
*/
while ((next < count) &&
(heapArr[next]).compareTo(temp) < 0)
{
heapArr[node] = heapArr[next];
node = next;
left = 2 * node + 1;
right = 2 * (node + 1);
if ((heapArr[left] == null) && (heapArr[right] == null))
next = count-2;
else if (heapArr[right] == null)
next = left;
else if (heapArr[left].compareTo(heapArr[right]) < 0)
next = left;
else
next = right;
}
heapArr[node] = temp; //Insert node at appropriate location
}
return unsortedArr;
Спасибо, это помогло. Наконец я понял, где и почему происходит исключение. Это потому, что левый и правый индексы выходили за пределы массива. Кроме того, установка слева и справа на 1 и 2 соответственно каждый раз, когда корень удаляется, на самом деле не так. Это связано с тем, что в этом impelentation я хочу каждый раз вставлять последний лист в корень, после удаления корня. Таким образом, его левый и правый ребенок будет по 1 и 2 каждый раз. –