У моих узлов дерева есть 3 строковых поля и 3 поля узла, которые левые, средние и правые.
Одна из проблем заключается в том, что метод может принимать только строку в качестве параметра
Это то, что у меня есть
public TreeNode findNode(String name) {
TreeNode pointer = this.getRoot();
if (pointer.getName().equals(name))
return pointer;
if (pointer.getLeft() != null)
pointer = pointer.getLeft();
findNode(name);
if (pointer.getMiddle() != null)
pointer = pointer.getMiddle();
findNode(name);
if (pointer.getRight() != null)
pointer = pointer.getRight();
findNode(name);
return null;
}
Это вызывает ошибку, потому что я просто продолжаю устанавливать указатель на root. Но я должен начать где-то, и моими единственными параметрами для метода можно назвать имя. Кажется, я не вижу, как это сделать.
Вы можете использовать список как стек параметров.
public TreeNode findNode(String name) {
List<TreeNode> stack = new ArrayList<TreeNode>();
stack.add(this.getRoot());
while (!stack.isEmpty())
{
TreeNode node = stack.remove(0);
if (node.getName().equals(name))
return node;
if (pointer.getLeft() != null)
stack.add(node.getLeft());
if (node.getMiddle() != null)
stack.add(node.getMiddle());
if (node.getRight() != null)
stack.add(node.getRight());
}
return null;
}
Вы можете удалить из конца списка, а не перед первой частью списка, если хотите сначала выполнить поиск по глубине.
Я предполагаю, что вы не можете изменить подпись этой функции. Имейте вспомогательную функцию, которая принимает два параметра, (Узел и имя), которые вы вызываете с именем root.
Используйте вспомогательный метод, который принимает параметр TreeNode
в дополнение к строке:
public TreeNode findNode(String name) {
return auxFindNode(this.getRoot(), name);
}
private TreeNode auxFindNode(TreeNode node, String name) {
//perform your recursive traversal here
}
Ваш код в его нынешнем виде никогда не будет работать, потому что вы продолжаете устанавливать pointer
на корень дерева в начале метода. Таким образом, все ваши рекурсивные вызовы начинаются с корня дерева.
Если вы предпочитаете не использовать другой метод, вы можете пересечь дерево итеративно с помощью стека:
public TreeNode findNode(String name) {
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode foundNode = null;
while(!stack.empty() && foundNode == null) {
TreeNode node = stack.pop();
if(node.getName().equals(name)) {
foundNode = node;
} else {
if(node.getLeft() != null) {
stack.push(node.getLeft();
}
if(node.getMiddle() != null) {
stack.push(node.getMiddle());
}
if(node.getRight() != null) {
stack.push(node.getRight());
}
}
}
return foundNode;
}
Во всех трех случаях (слева, в середине, справа) вы вызываете findNode(name)
но не для этих объектов, вместо этого для this
. Вот почему вы получаете переполнение стека.