Пример программы удаления узла из дерева
procedure del ( var root : tree ; key : integer ); var p : tree ; {удаляемый узел} parent : tree ; {предок удаляемого узла} y : tree ; {узел, заменяющий удаляемый} function spusk(p:tree):tree; var y : tree ; {узел, заменяющий удаляемый} pred:tree; { предок узла “y”} begin y:=p^.right; if y^.left=nil then y^.left:=p^.left {1} else {2} begin repeat pred:=y; y:=y^.left; until y^.left=nil; y^.left:=p^.left; {3} pred^.left:=y^.right; {4} y^.right:=p^.right; {5} end; spusk:=y; end; begin if not find(root, key, p, parent) then {6} begin writeln(‘ такого элемента нет ’); exit; end; if p^.left=nil then y:=p^.right {7} else if p^.right=nil then y:=p^.left {8} else y:=spusk(p); {9} if p=root then root:=y {10} else {11} if key<parent^.inf then parent^.left:=y else parent^.right:=y; dispose(p); {12} end.
В функцию del передаются указатель root на корень дерева и ключ key удаляемого элемента. С помощью функции find определяются указатели на удаляемый элемент p и его предка parent . Если искомого элемента в дереве нет, то выдается сообщение ( {6}) .
В операторах {7}-{9} определяется указатель на узел y , который должен заменить удаляемый. Если у узла p нет левого поддерева, на его место будет поставлена вершина (возможно пустая) его правого поддерева ({7}).
Иначе, если у узла p нет правого поддерева, на его место будет поставлена вершина его левого поддерева ({8}).
В противном случае, когда оба поддерева существуют, для определения замещающего узла вызывается функция spusk , выполняющая спуск по дереву ({9}).
В этой функции первым делом проверяется особый случай, описанный выше ({1}). Если же этот случай (отсутствие левого потомка у правого потомка удаляемого узла) не выполняется, организуется цикл ({2}), на каждой итерации которого указатель на текущий элемент запоминается в переменной pred , а указатель y смещается вниз и влево до того момента, пока не станет ссылаться на узел, не имеющий левого потомка (он-то нам и нужен).
В операторе {3} к этой пустующей ссылке присоединяется левое поддерево удаляемого узла. Перед тем как присоединять к этому узлу правое поддерево удаляемого узла ({5}), требуется «пристроить» его собственное правое поддерево. Мы присоединяем его к левому поддереву предка узла y , заменяющего удаляемый ({4}), поскольку этот узел перейдет на новое место.
Функция spusk возвращает указатель на узел, заменяющий удаляемый. Если мы удаляем корень дерева, надо обновить указатель на корень ({10}), иначе – присоединить этот указатель к соответствующему поддереву предка удаляемого узла ({11}).
После того как узел удален из дерева, освобождается занимаемая им память ({12})