經過重大的重新格式化工作之後,我將您的代碼重構爲更清晰的形式。雖然實質上不同,以下是邏輯上等同於您的代碼:
private Node<K, V> getNode(K key, ArrayList<Node<K, V>> children){
if (children == null) return null;
if (root.getKey().equals(key)) return root;
for (Node<K,V> child : children) {
if (child.getKey().equals(key)) return child;
getNode(key, child.getChildren());
}
return null;
}
現在,我們可以挑選除了代碼,並修復它。
第一個問題是,您沒有在方法前記錄javadoc註釋並記錄其參數並返回@param
和@return
。這就是你需要解決的問題。
其次,此方法應作爲Node
類的類方法實施,並應爲public
。那就是:
class Node<K,V> {
// ... whatever else this class has in it ...
public K getKey() { /* ... stuff ... */ }
ArrayList<Node<K,V>> children = new ArrayList<>();
public Node<K, V> getNode(K key){
if (children == null) return null;
if (key.equals(this.getKey())) return this;
for (Node<K,V> child : children) {
if (child.getKey().equals(key)) return child;
child.getNode(key);
}
return null;
}
}
而且,因爲我們現在已經保證了children
總是被初始化,並且完全在我們的控制之下,我們可以擺脫虛假null
檢查。
public Node<K, V> getNode(K key){
if (key.equals(this.getKey())) return this;
for (Node<K,V> child : children) {
if (child.getKey().equals(key)) return child;
child.getNode(key);
}
return null;
}
現在,你是冗餘檢查孩子。由於getNode()
已經檢查是否this
是正確的節點,沒有理由單獨檢查當前節點的每個孩子
public Node<K, V> getNode(K key){
if (key.equals(this.getKey())) return this;
for (Node<K,V> child : children)
child.getNode(key);
return null;
}
現在,我們已經擺脫了這麼多的代碼,它應該是相當明顯的是什麼問題實際上是:上層方法實際上從未實際上通過搜索孩子找到節點。一個簡單的改變就足以解決這個問題,雖然:
public Node<K, V> getNode(K key){
if (key.equals(this.getKey())) return this;
for (Node<K,V> child : children){
Node<K,V> result = child.getNode(key);
if(result != null) return result;
}
return null;
}
請注意,我們不應該被檢查,如果孩子是null
。這應該由我們暴露了添加新值的方法來處理,我們不應該將國外的節點到樹:
public boolean put(K key, V value){
children.add(new Node<>(key, value));
}
還有一兩件事:有沒有必要一個單獨的Tree
類在所有!你不應該有一個,它的所有功能應該完全存在於節點類中。理想情況下,根節點是樹。
'如果(root.getKey()等於(鍵)。) { 返回根; }' 應該是'如果外部(孩子!= NULL)'塊 –