Я работаю над заданием, которое просит меня реализовать дерево AVL. Я почти уверен, что у меня правильные методы поворота, но мне сложно понять, когда их использовать.
Например, объяснение в книге говорит, что я должен подняться по тому же пути, по которому я пошел, чтобы вставить узел / элемент. Однако у меня не может быть родительских указателей.
Последний код:
public BinaryNode<T> insert(BinaryNode<T> node) {
if (this.getElement().compareTo(node.getElement()) > 0) {
if (this.getLeftChild() != null) {
BinaryNode<T> b = this.getLeftChild().insert(node);
if(!this.isBalanced()) {
this.balance();
}
return b;
} else {
this.setLeftChild(node);
}
} else if (this.getElement().compareTo(node.getElement()) < 0) {
if (this.getRightChild() != null) {
return this.getRightChild().insert(node);
} else {
this.setRightChild(node);
}
}
return this;
}
То, что я хочу сделать здесь, это забраться обратно вверх по дереву, но он может проверить баланс только ПОСЛЕ того, как вставит узел. Следовательно, это в предложении else.
Я также попытался поместить код баланса, где предложил R Samuel Klatchko, но проверил баланс на каждой вставке. Например: если вставить последовательно 7, 9, 5, 3 и 1, я получаю исключение нулевого указателя при попытке вставить 1.
РЕДАКТИРОВАТЬ: Одна из причин для вышеизложенного может иметь отношение к тому, как я делал высоту. Он отлично работает с одним поворотом вправо, если я вычисляю высоту каждый раз с помощью height (), но это нарушает время O (log (n)) дерева AVL.
Есть мысли о том, как этого добиться?