我目前正在做一個任務,我需要在一個陣列中使用一個帶有連接頂點的圖形。我需要計算圖中的每個節點,并嘗試遞回地進行。
public int getAmountOfNodes(Node node, int countFrom){
for (Node n : node.children) {
if (n != null) {
countFrom ;
getAmountOfNodes(n, countFrom);
}
}
return countFrom;
}
到目前為止,這是我嘗試過的,但它并沒有按照我希望的方式進行。我試圖除錯代碼,似乎計數作業方式應該是(計算每個不為空的節點)。問題似乎是當遞回堆疊結束時,假設 countFrom 已經達到 5,并且該方法回傳 5,堆疊中的下一個遞回呼叫不會“記住這一點”,而是回傳它之前計數的數量,比如說 4。這意味著最終回傳的整數只是第一個遞回呼叫所計數的數量,即第一個節點擁有的子節點數量。
我一直在嘗試用谷歌搜索,但找不到我可以使用的答案。我還在學習遞回,所以請原諒我面前可能出現的任何愚蠢的錯誤。
任何幫助將不勝感激,將提供所需的任何資訊。謝謝!
uj5u.com熱心網友回復:
您可以使用廣度優先搜索,無需遞回呼叫即可實作。如果當前節點的每個子節點 n 第一次被訪問,則將其添加到 FIFO 佇列中。在檢查了當前節點的子節點后,從佇列中洗掉另一個當前節點。
uj5u.com熱心網友回復:
在您的代碼中,您只需將 countFrom 原始 int 傳遞給每個呼叫,而無需費心從上次呼叫中更新其值。這就是為什么您的最后一次迭代沒有達到最終結果的原因,這也解釋了為什么在您的示例中您得到 4 而不是 5。
在設計遞回方法時,您應該始終考慮所有基本案例和遞回案例。在此示例中,您的基本情況(結束遞回迭代的場景)可能是n == null遞回步驟(使您朝著目標前進的動作)是計數變數的增量及其在遞回呼叫后的更新。
您的代碼應該看起來像這樣。
public int getAmountOfNodes(Node n, int countFrom){
//Checking whether n actually represents a node or not; if it's not then the number of nodes stays the same
if (n == null){
return countFrom;
}
//If n represents a node then the numer of nodes must be incremented
countFrom ;
//Aplying the previous logic to each children of n
for (Node child: n.children) {
//Doesn't matter whether child is null or not; if child is null then countFrom stays the same
//otherwise it's incremented according to the number of nodes met by the recursive call
countFrom = getAmountOfNodes(child, countFrom);
}
return countFrom;
}
uj5u.com熱心網友回復:
堆疊中的下一個遞回呼叫不“記住這個”,并回傳它之前計數的數量
因為您沒有使用呼叫回傳的值:
getAmountOfNodes(n, countFrom);
每次呼叫都會創建一個新的遞回分支,但回傳值不受影響。
還有幾個小問題:
- 您不需要第二個引數,只需回傳累積值而不是維護冗余引數;
- 您計算沒有子節點的節點的方式并不直觀;
- 一個好的做法是在可能的情況下禁止可以為空的值,這使您的邏輯更簡單,生活更輕松。
null在對鏈表等資料結構進行建模時,您無法避免使用值,但在圖中,如果節點沒有子節點而不是值的集合,則該節點null應該包含一個空集合。
public int getAmountOfNodes(Node node) {
int count = 1; // we sould count THIS node
for (Node child : node.children) {
if (child == null) continue;
count = getAmountOfNodes(child);
}
return count;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/463337.html
下一篇:看不懂多重遞回的流程
