2016-04-01 63 views
0

我一定是缺少的東西簡單,因爲這是在吹我的腦海!程序拋出異常後,我檢查了異常

我想實現一個堆使用CompleteBinaryTree(這是使用數組實現)。 CompleteBinaryTree是一個Position<T>的數組,其中每個Position都包含一個元素。我正在爲Heap寫入add(T t)方法,其中t被插入CompleteBinaryTree的下一個空閒位置,然後執行upheap進程,直到CompleteBinaryTree被排序。下面是該方法:

private CompleteBinaryTree<T> tree = new CompleteBinaryTree<T>(); 
    private Position<T> entry = null; 

    public void add(T t) { 
     entry = tree.add(t); 

     if (entry.equals(tree.root())) { 
      return; 
     } 

     //continue to swap inserted element with its parent 
     //while it is smaller than its parent 
     while (entry.element().compareTo(tree.parent(entry).element()) < 0) { 
      Position<T> parent = tree.parent(entry); 
      Position<T> temp = entry; 
      entry = parent; 
      parent = temp; 
     } 
    } 

第一元素被添加細到堆,但是當我嘗試添加所述第二元件,InvalidPositionException是在while()線拋出。這就是exeption正在從CompleteBinaryTree類中拋出:

public Position<T> parent(Position<T> p) { 
     if (p == root()) throw new InvalidPositionException(); 

     return array[((ArrayPosition) p).index/2]; 
    } 

而且這裏距離CompleteBinaryTree使用其他兩種方法:

public Position<T> root() { 
     if (isEmpty()) throw new InvalidPositionException(); 
     return array[1]; 
    } 

    public Position<T> add(T t) { 
     if (last == array.length) { 
      // extend array 
      ArrayPosition[] temp = (ArrayPosition[]) new Object[array.length*2]; 
      for (int i=1; i < array.length; i++) { 
       temp[i] = array[i]; 
      } 
      array = temp; 
     } 

     array[last] = new ArrayPosition(last, t); 
     return array[last++]; 
    } 

我如何得到一個異常拋出,因爲p == root(),當我首先檢查p是否是根?

編輯

這裏是CompleteBinaryTree toString(),這是由堆toString()返回:

public String toString() { 
    StringBuffer buf = new StringBuffer(); 

    for (int i = 1; i < last; i++) { 
     buf.append(" ").append(array[i]); 
    } 

    return buf.toString();  
} 
+0

'root()'可能正在拋出。 – SLaks

+0

但在引發異常之前,如果'entry'是根,則返回該方法,但是因爲'entry'是根,所以引發異常? – KOB

+0

你調試了嗎?如果在if(p == root())或if(isEmpty())''時出現異常,那麼您將新的InvalidPositionException();移到新行 –

回答

2

我如何得到一個異常拋出,因爲p ==根(),當我首先檢查p是否是根?

但你檢查每個tree.parent()說法,看它是否是根。您只檢查傳遞給該方法的第一個調用的參數。每次執行while循環的主體時,它都會將entry設置爲新值,並且當循環將新的未選中值傳遞給tree.parent()時。實際上,entry的每個新值都比前一個更接近根,因爲整個觀點是從樹向上移動樹,即朝向根。有時候這個過程有可能會達到根源,這很可能是樹中已經存在的元素越少。要解決這個

一種方式是移動根檢查到while條件:

while (!entry.equals(tree.root()) 
     && entry.element().compareTo(tree.parent(entry).element()) < 0) { 
    // ... 
} 

在這種情況下,當然,你並不需要您執行外目前一次性檢查循環。

+0

啊,是的,我從未想過。這一切都非常有意義,而且看起來,所有事情都像現在這樣。謝謝 – KOB

+0

然而,它似乎沒有被訂購堆。當我將元素添加到堆中並打印堆的狀態時,它將以與將元素插入堆中的相同方式排序。另外,無論添加到堆中的元素是什麼 - 如果在每次插入後打印根值,它始終是我插入的第一個元素的值(這對我來說是沒有意義的,因爲之前它在拋出異常時新插入的元素被交換到根位置)。看到我的原始文章,我將添加'toString()'方法 – KOB

+0

@KOB,那個額外的問題不是這個問題的主題,但我注意到儘管你的'add()'方法遍歷樹從葉到根,它似乎沒有做任何重新排序任何節點的事情。特別是,像「entry = parent」這樣的代碼並不這樣做 - 它只是改變哪個節點局部變量entry指向哪個節點。當你走的時候,你可能還想交換'位置'的內容,但這是我的猜測。 –