Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Prolog > Удаление поддерева


Автор: mChief 27.12.2008, 20:00
Нужен предикат для удаления поддерева из двоичного дерева начиная  с заданой вершины.

Автор: Фантом 27.12.2008, 20:30
А в каком виде хранится дерево?

Автор: mChief 28.12.2008, 00:38
Забыл написать

tree=inttree(integer,inttree,inttree);end

Автор: Фантом 28.12.2008, 02:59
Ну так очевидно же:
Код

deltree(end,_,end).
deltree(A,N,B):-A=inttree(N,_,_),B=end,!.
deltree(A,N,B):-A=inttree(M,A1,A2),deltree(A1,N,B1),deltree(A2,N,B2),B=inttree(M,B1,B2).

Автор: mChief 28.12.2008, 14:35
Спасибо

Автор: mChief 28.12.2008, 20:02
Можно еще ворос. Как удалить один элемент и при этом перераспределить все элементы которые были ниже?

Автор: Фантом 28.12.2008, 20:49
Перераспределить куда? Ниже два поддерева, поэтому способ перераспределения неочевиден.

Автор: mChief 28.12.2008, 21:06
Будем считать что дерево упорядоченное, например меньшие слева, большие справа. Тогда все элементы из нижних поддеревьев распределить по этому правилу

Автор: Фантом 28.12.2008, 23:47
Это все равно неоднозначное условие. Ну, например, есть вершины с номерами 1,2,3 - в какое дерево их надо собрать?

Автор: mChief 29.12.2008, 04:54
Условие однозначное, это бинарное дерево. Вершины 1,2,3 соберутся в дерево:
Код

                 1
                       2
                            3

если бы порядок был, например, 2,1,3 то получилось бы:
Код

                      2
                1         3

Кстати решение нашел, может кому пригодится
Код

 Вспомогательный предикат, удаляющий минимальный элемент бинарного дерева.
delete1 (tr (nil, Y, R), Y, R).
/* Если левое поддерево пусто, то минимальный элемент - корень, а дерево без
 минимального элемента - это правое поддерево.*/
delete1 (tr (L, K, R), Y, tr (L1, K, R)):-
     delete1 (L, Y, L1).
/* Левое поддерево не пусто, значит, оно содержит минимальное значение всего
 дерева, которое нужно удалить */
    Основной предикат, выполняющий удаление вершины из дерева, будет выглядеть следующим образом.

delete (tr (nil, X, R), X, R, 0):-
     nl, write ("Элемент из дерева удален.").
/* X совпадает с корневым значением исходного дерева, левое  поддерево пусто */
delete (tr (L, X, nil), X, L, 0):-
     nl,write("Элемент из дерева удален.").
/* X совпадает с корневым значением исходного дерева, правое поддерево пусто */
delete (T, _, T, 1):-
     nl,write ("Такого элемента нет!!!").
/*четвертый аргумент 1, поэтому такого элемента в дереве нет.*/
delete (tr (L, X, R), X, tr (L, Y, R1), _):-
     delete1(R,Y,R1).
/* X совпадает с корневым значением исходного дерева, причем ни левое,
 ни правое поддеревья не пусты */
delete (tr (L, K, R), X, tr (L1, K, R), H):-
     X<K,
     delete(L,X,L1,H).
/* X меньше корневого значения дерева */
delete (tr (L, K, R), X, tr (L, K, R1), H):-
     X>K,
     delete (R, X, R1, H).
/* X больше корневого значения дерева */

Автор: Фантом 30.12.2008, 02:40
А, ясно. Стормозил.  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)