Довольно сложно сделать на Java настоящую реализацию универсального дерева, которая действительно отделяла бы операции и свойства дерева от базовых реализаций, т. е. заменяла RedBlackTreeNode и переопределяла пару методов, чтобы получить реализацию RedBlackTree, сохраняя при этом все общие операции, которые выполняет BinaryTree. интерфейс содержит.
Кроме того, идеальная абстракция могла бы заменить низкоуровневое представление дерева, например. неявная двоичная древовидная структура, хранящаяся в массиве для кучи или базового интерфейса узла с левыми и правыми дочерними указателями или несколькими дочерними указателями, или дополнение любого из вышеперечисленного родительскими указателями, или потоки конечных узлов и т. д. и т. д., и Т. Д.
Я пытался решить эту проблему сам, но в итоге получил довольно сложный интерфейс, который по-прежнему обеспечивает безопасность типов. Вот основа идеи создания абстрактного класса BinaryTree с нетривиальной операцией (Euler Tour), которая будет работать, даже если базовый класс узла или класс дерева изменен. Вероятно, его можно было бы улучшить, представив идею курсоров для навигации и позиций в древовидной структуре:
public interface Tree<E, P extends Tree.Entry<E, P>> extends Collection<E>
{
public P getRoot();
public Collection<P> children(P v);
public E getValue(P v);
public static interface Entry<T, Q extends Entry<T, Q>> { }
}
public interface BinaryTree<E, P extends BinaryTree.Entry<E, P>> extends Tree<E, P>
{
public P leftChild(P v);
public P rightChild(P v);
public static interface Entry<T, Q extends Entry<T, Q>> extends Tree.Entry<T, Q>
{
public Q getLeft();
public Q getRight();
}
}
public interface TreeTraversalVisitor<E, P extends BinaryTree.Entry<E, P>, R>
{
public R visitLeft( BinaryTree<E, P> tree, P v, R result );
public R visitCenter( BinaryTree<E, P> tree, P v, R result );
public R visitRight( BinaryTree<E, P> tree, P v, R result );
}
public abstract class AbstractBinaryTree<E, P extends BinaryTree.Entry<E, P>> extends AbstractCollection<E> implements BinaryTree<E, P>
{
public Collection<P> children( P v )
{
Collection<P> c = new ArrayList<P>( 2 );
if ( hasLeft( v ))
c.add( v.getLeft());
if ( hasRight( v ))
c.add( v.getRight());
return c;
}
/**
* Performs an Euler Tour of the binary tree
*/
public static <R, E, P extends BinaryTree.Entry<E, P>>
R eulerTour( BinaryTree<E, P> tree, P v, TreeTraversalVisitor<E, P, R> visitor, R result )
{
if ( v == null )
return result;
result = visitor.visitLeft( tree, v, result );
if ( tree.hasLeft( v ))
result = eulerTour( tree, tree.leftChild( v ), visitor, result );
result = visitor.visitCenter( tree, v, result );
if ( tree.hasRight( v ))
result = eulerTour( tree, tree.rightChild( v ), visitor, result );
result = visitor.visitRight( tree, v, result );
return result;
}
}
person
Lucas
schedule
01.06.2010