Ответ 1
При попытке удалить data
из вашего дерева двоичного поиска есть три основные возможности:
-
data
меньше текущего значения node: Вызов удаляется в левом поддереве или бросаетNoSuchElementException
, если он равен нулю. -
data
больше, чем текущее значение node: вызывать удаление в правом поддереве или бросать aNoSuchElementException
, если оно равно null. -
data
равен текущему значению node.
1 и 2 довольно просты, но 3 имеет еще четыре случая:
3,1. текущий node - это лист. Оба левого и правого поддеревьев равны нулю. Просто замените ссылку на текущий node на родительский на null.
3,2. текущий node имеет только левый дочерний элемент: вам нужно сделать родительский текущего node точкой в левом поддереве, тем самым удалив текущую точку. Для этого вы можете реализовать функцию, которая будет проверять, находилась ли текущая точка в левом или правом поддереве родительский, и замените ее соответствующим образом. Вызов будет выглядеть так:
replaceNodeInParent(node, node.getLeft(), parent);
3.3. текущий node имеет только правильный дочерний: аналогично 3.4, но использует getRight()
вместо getLeft()
.
3.4. текущий node имеет как левый, так и правый дочерние элементы. Вы должны сохранить свойство BST, что все узлы слева меньше текущего node, а все узлы справа больше, чем текущий node. Для этого вы должны найти наименьшее значение справа, скопировать его в текущий node и удалить его из правого поддерева. Что-то вроде этого:
BSTNode<T> successor = findMin(node.getRight());
node.setData(successor.getData());
removeRec(node.getRight(), successor.getData(), node);
Похоже, ваш BSTNode
не содержит ссылку на родительский node. Если это так, я считаю, что должен быть третий аргумент для removeRec
. Вам понадобится ссылка на родительский при каждом замене текущего node, поэтому вы можете установить родительское левое или правое поддерево по мере необходимости.
Для дальнейшего чтения вы можете проверить эту статью статью о деревьях двоичного поиска из Википедии.