Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Derevo.doc
Скачиваний:
5
Добавлен:
08.08.2019
Размер:
147.97 Кб
Скачать

Пример программы удаления узла из дерева

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})

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]