我的Heap Sort代码在Java中有什么问题?

时间:2014-04-03 15:59:33

标签: java sorting heap heapsort

我试图在Java中使用此数组创建和排序堆。我在maxHeap函数中不断获得数组索引超出范围的异常。代码似乎对我有意义,所以我不确定错误的来源。

任何人都知道我做错了什么?

 public static void main(String[] args) {
    int[] array = { 5, 16, 10, 7, 43, 12, 75, 33, 47, 3, 2489, 591, 6639, 557, 84, 9054, 17, 8841, 99, 701, 21, 78, 9, 36, 839};
    heapSort(array3);
    System.out.println("Heap Sort:");
    printArray(array3);
}

public static void createHeap(int []A){
    int n = A.length-1;
    for(int i=n/2;i>=0;i--){
        maxheap(A,i);
    }
}

public static void maxheap(int[] A, int i){ 
    int n = A.length;
    int largest;
    int left=2*i;
    int right=2*i+1;
    if(left <= n && A[left] > A[i]){
        largest=left;
    }
    else{
        largest=i;
    }

    if(right <= n && A[right] > A[largest]){
        largest=right;
    }
    if(largest!=i){
        int temp=A[i];
        A[i]=A[largest];
        A[largest]=temp;
        maxheap(A, largest);
    }
}

public static void heapSort(int []A){
    createHeap(A);
    int n= A.length;
    for(int i=n;i>0;i--){
        int temp=A[0];
        A[0]=A[i];
        A[i]=temp;
        n=n-1;
        maxheap(A, 0);
    }
}


public static void printArray(int[] sortedArray) {

   for (int i = 0; i < sortedArray.length; i++) {
       System.out.print(sortedArray[i] + ", ");
   }
   System.out.println("");
}

2 个答案:

答案 0 :(得分:5)

Java中的数组是zero-indexed。您将循环上限(n)设置为A.length,然后对其执行小于或等于比较,因此它将始终检查一个太多的元素。

if(left <= n && A[left] > A[i]){

应该是

if(left < n && A[left] > A[i]){

if(right <= n && A[right] > A[largest]){

应该是

if(right < n && A[right] > A[largest]){

您还在执行狡猾的操作以初始化rightcreateHeap()i设置为等于n/2(这可能是一个错误)。然后,您以参数maxHeap的形式将此值传递给i。那你就是这样做的:

int right = 2*i+1;

i说2时,会发生什么?

为了i2A.length必须为56(因为createHeap设置nA.length - 1(5 - 1) / 2 = 4(6 - 1) / 2相同。当这种情况逐渐传递到maxheap时,2 * i + 1会将您带到5,这超出A的界限(可能是长度,但如果是这样的话)在这种情况下,4是最高的索引,而不是5)。

所以,这是A.length = 5

时的情况
if(right <= n && A[right] > A[largest]) {
   ^ 5      ^ 5    ^ ArrayIndexOutOfBoundsException thrown here.

right <= n评估为true,因为5确实等于5,因此评估A[right],并在您的例外情况下立即失败。对right < n进行简单的 检查会阻止此操作,因为5不小于5,因此第一个条件的计算结果为false,从而确保A[right]根本不会得到评估。

简而言之 - 这对于奇数长度的数组不起作用。

请记住:数组的.length属性会告诉您 包含的元素数量 最后一个元素。

答案 1 :(得分:1)

您宣布int n三次,第一次为:

int n = A.length - 1;
createHeap()

中的

第二次:

int n = A.length;

maxHeap()和第三次:

int n = A.length;
heapSort();

中的

maxHeap() right设置为25,因此A[right](A [25])超出范围

您可以int n = A.lengthheapSort()之间留下maxHeap()