Для удаления узла возможны три сценария.
- Узел является листовым узлом: это простой случай, выясните, является ли этот узел левым или правым узлом родительского узла, и установите нулевое значение в качестве дочернего для родителя для этой стороны.
- У узла есть один дочерний узел: установите прямую связь между родительским узлом и дочерним узлом этого узла.
- У узла двое детей: это немного сложно ... шаги, которые нужно сделать, это.
- Сначала найдите преемника (или предшественника) этого узла.
- Удалить преемника (или предшественника) из дерева.
- Заменить удаляемый узел преемником (или предшественником)
Прежде чем знать концепцию удаления, мы должны понять концепцию преемника и предшественников
Преемник: в двоичном дереве наследником узла является наименьший узел дерева, который строго больше этого узла.
Есть два возможных случая с узлом
У узла есть правые дочерние элементы: в этом случае самый левый дочерний элемент правого поддерева будет преемником.
Узел не имеет дочерних элементов: перейдите к родительскому узлу и найдите узел, для которого этот узел является частью левого поддерева.
public Node sucessor(Node node) {
Node sucessor = null;
if (node.getRightNode() != null) {
Node newNode = node.getRightNode();
while (newNode != null) {
sucessor = newNode;
newNode = newNode.getLeftNode();
}
} else {
sucessor = findRightParent(node);
}
return sucessor;
}
private Node findRightParent(Node node) {
Node newNode = null;
if (node.getParentNode() != null) {
if (node.getParentNode().getLeftNode() == node) {
newNode = node.getParentNode();
} else {
newNode = findRightParent(node.getParentNode());
}
}
return newNode;
}
Теперь логика удаления
public void deleteNode(Node node) {
// Node is a leaf node //
if( node.getLeftNode() == null && node.getRightNode() == null){
if(isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(null);
}else{
node.getParentNode().setLeftNode(null);
}
// Only left child is there//
}else if( node.getLeftNode() != null && node.getRightNode() == null){
if(isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(node.getLeftNode());
}else{
node.getParentNode().setLeftNode(node.getLeftNode());
}
// Only Right child is there //
}else if( node.getLeftNode() == null && node.getRightNode() != null){
if( isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(node.getRightNode());
}else{
node.getParentNode().setLeftNode(node.getRightNode());
}
// Both Left and Right children are their//
}else{
Node psNode = predessor(node);
deleteNode(psNode);
psNode.setParentNode(node.getParentNode());
psNode.setLeftNode(node.getLeftNode());
psNode.setRightNode(node.getRightNode());
if( isRightNode(node.getParentNode(), node)){
node.getParentNode().setRightNode(psNode);
}else{
node.getParentNode().setLeftNode(psNode);
}
}
}
Решение взято из http://coder2design.com/binary-tree/
Также они объяснили ход прохождения и вставки с полным исходным кодом.