【问题标题】:Array index out of bounds java heap [duplicate]数组索引越界java堆[重复]
【发布时间】:2014-12-05 20:07:04
【问题描述】:

我知道这是一个错误,我理解它的含义,但我不明白为什么我无法修复它。我一直在尝试一切。我试图获取一个类型为 T 的数组并切换它的值,以便它正确地对应于堆的规则,其中父级总是大于 2 个子级。错误在我的while循环中

如果它很容易修复,请不要苛刻。我一直在苦苦挣扎,似乎找不到答案。

public class myheap<T extends Comparable<T>> extends heap<T>
{ 
    // constructors of the subclass should be written this way:
    public myheap(int max) { super(max); }
    public myheap(T[] A) {super(A);}  


    public void buildheap(T[] Arr){ 
        int size = Arr.length;
        int startsize = (size-1)/2;
        for(int i=startsize;i>0;i--){
            int l = left(i);
            int r = right(i);
            T temp = null;
            while((Arr[r]!=null) && Arr[i].compareTo(Arr[r])<0){
                if (Arr[l].compareTo(Arr[r])>0){
                    temp = Arr[l];
                    Arr[l] = Arr[i];
                    Arr[i] = temp;
                }//if left is greater than right
                else        //then right must be greater than parent            
                    temp = Arr[r];
                    Arr[r] = Arr[i];
                    Arr[i] = temp;
            }//whileloop
            if((Arr[r]==null) && Arr[i].compareTo(Arr[l])<0)
                temp = Arr[l];
                Arr[l] = Arr[i];
                Arr[i] = temp;
        }//for

    }//buildheap


    public static void main(String[] args){
        String[] array = {"SH","AH","AB","YA","AY","AA","AB","LM","LL","LO"};
        myheap<String> New = new myheap<String>(array.length);
        for(int i=0;i<array.length;i++){
            New.insert(array[i]);
        }//insert
        New.buildheap(array);
        New.drawheap();
        for(int i=0;i<array.length;i++){
            System.out.println(New.deletemax() + "  ");
        }//for
        System.out.println();

    } //main

}

myheap 正在扩展的堆超类

/*
  Polymorphic priority heaps, largest value on top.
  Heap axiom.  The value at every node cannot be smaller than the values
  at each of its children nodes.
  Use internal array to implement heap "tree", with index 0 representing
  the root.  Given node index i, left(i)= 2*i+1 and right(i)=2*i+2, while
  parent(i) = (i-1)/2.
*/

class heap<T extends Comparable<T>>
{
  protected T[] H; // internal array representing heap.
  protected int size; // size of current heap, not same as H.length!
  public int size() { return size; } // size is read-only externally.
  public int maxsize() { return H.length; }
  public heap(T[] A) { H = A; size=0; } // preferred constructor
  public heap(int m) // will cause compiler warning (ok to ignore)
  {
     H = (T[]) new Comparable[m]; // downcast from Object is OK.
     size = 0;
  }

  protected int left(int i) { return 2*i+1; }
  protected int right(int i) { return 2*i+2; }
  protected int parent(int i) { return (i-1)/2; }

  // protected is important!

  // lookup heap, without delete
  public T getmax()
  { 
    if (size<1) return null; 
    return H[0];
  }

  // insert x into heap: place at end, then propagate upwards
  // returns false on failure.
  public boolean insert(T x)
  {
     if (size > H.length-1) return false;
     H[size++] = x; // place at end, inc size
     // propagate upwards
     int cur = size-1; // current position
     int p = parent(cur);
     while (cur>0 && H[cur].compareTo(H[p])>0)
     { // propagate upwards
       T temp = H[cur];
       H[cur] = H[p];  H[p] = temp;
       cur = p;  // switch current to parent
       p = parent(cur); // recalc parent
     }//while
     return true;
  }//insert

// deletetop: take last element, move to top, propagate downwards:
  public T deletemax()
  {
     if (size<0) return null;
     T answer = H[0];
     H[0] = H[--size]; // place at top:
     // now propagate downwards.
     boolean done = false;
     int i = 0; // current position
     int c = 0; // swap candidate
     while (c != -1)
     {
     int l = left(i);
     int r = right(i);
     c = -1; // swap candidate
     if (l<size && H[l].compareTo(H[i])>0) c = l; // set candidate to left
     if (r<size && H[r].compareTo(H[i])>0 && H[r].compareTo(H[l])>0) c=r;
     if (c!= -1) 
         {
         T temp = H[i];  H[i] = H[c]; H[c] = temp;
         i = c; 
         }
     }//while
     return answer;
  }//deletemax


    // but search is not log(n). Why?
  public boolean search(T x)
    {
    for(int i=0;i<size;i++) {if (x.compareTo(H[i])==0) return true;}
    return false;
    }

  public void drawheap() // use only with heapdisplay.java program
  {
      heapdisplay W = new heapdisplay(1024,768);
      W.drawtree(H,size);
  }

}//heap


public class heaps14
{
    /**public static void main(String[] args){
    heap<Integer> HI = new heap<Integer>(200);
    for(int i=0;i<100;i++) HI.insert((int)(Math.random()*1000));
    HI.drawheap();
    for(int i=0;i<100;i++) System.out.print(HI.deletemax() + "  ");
    System.out.println();
    }//main**/
}

【问题讨论】:

  • 您是否尝试过调试您的应用程序?
  • 2*i+2 最终会大于数组的大小。例如11 元素数组,i 将循环 0-&gt;52*i+2 将评估为 12
  • 数组索引越界异常:10,@MarcB 这就是为什么我指定如果 Arr[r]!= null 或 null,
  • 这毫无意义。 Arr[12] != null 将失败,因为您已经超出了数组的末尾。 java 甚至不会费心尝试测试无效性,因为您显然已经超出了数组的大小。你基本上表现得像个威利的郊狼,想知道为什么你从人行道尽头跑下来后会摔倒。
  • 这是很多代码供我们查看。 @SotiriosDelimanolis 建议调试代码是最好的第一步 IMO

标签: java arrays heap-memory


【解决方案1】:

您可以在 while 循环中检查 null (Arr[r]!=null),但问题是您甚至无法从数组中获取值以确定它是否为 null。在尝试访问数组中的值之前,您应该检查索引是否在范围内,使用 r &lt; Arr.length 或类似方法。

【讨论】:

  • 所以我想确保我的左右孩子不会返回一个不在我的数组大小中的 i 值?
  • @BenjiWeiss 可能吗?我没有时间阅读你所有的代码,但上面是跳出来的。通常,每当您访问数组的元素时,您都需要确保索引是合法值。
  • 我正确地确保 r 和 l 是
  • 多亏您的帮助,我才开始运行,谢谢,非常感谢
【解决方案2】:

(If null) 不是问题,arrayIndexOutofBounds 意味着您正在获取一个不存在的数组的值 例如。数组长度=5;然后你搜索 Array[6]; - 越界....

我认为问题在于你的方法对(i); 这是。 i*2+2 和数组

所以把for循环改成这个

 for(int i=startsize-2;i>0;i--)

如果有帮助,请发表评论。

【讨论】:

  • 我没有更改我的 for 循环,而是嵌套了我的 while 循环以确保我的索引保持在界限内。我现在的问题是我在同一个while循环中得到一个空指针异常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-28
  • 2013-03-05
相关资源
最近更新 更多