具有3个Java子节点的树的迭代器实现

时间:2015-04-27 14:40:15

标签: java tree iterator

对于大学我应该将Interface Iterator实现为具有3个孩子的树的内部类。 我对树的实现看起来像这样:

import java.util.*;

public class TernaerTree <E> {

    private TernaerTree left;
    private TernaerTree right;
    private TernaerTree middle;
    private E value;

    public E getValue() {
        return value;
    }

    public TernaerTree(TernaerTree left, TernaerTree middle, TernaerTree right, E value) {
        this.left = left;
        this.right = right;
        this.middle = middle;
        this.value = value;
    }

    public static void main(String [] args){

        TernaerTree <String> baum = new TernaerTree<String>(new TernaerTree<String>(null,null,null,"Hallo"),new TernaerTree<String>(null,null,null,"Welt"),new TernaerTree<String>(null,null,null,"?"),"!");
    }

    public class WalkThroughIterator implements Iterator {

        @Override
        public boolean hasNext() {
        }

        @Override
        public Object next() {
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("remove() is not supported.");
        }

    }

}

现在我应该实现WalkthroughIterator。它应该通过这个顺序遍历树:左,中,右和节点本身。迭代器应该使用recomursive子树的迭代器。

在mainmethod中,一切都应该打印在屏幕上。

希望有人可以帮助我。

谢谢, 托拜厄斯

3 个答案:

答案 0 :(得分:2)

这似乎有效 - 它使用iterator列表来跟踪内部树木。一旦它们全部耗尽,它就会发出元素。

public class TernaerTree<E> implements Iterable<E> {

    private TernaerTree left;
    private TernaerTree middle;
    private TernaerTree right;
    private E value;

    public E getValue() {
        return value;
    }

    public TernaerTree(TernaerTree left, TernaerTree middle, TernaerTree right, E value) {
        this.left = left;
        this.middle = middle;
        this.right = right;
        this.value = value;
    }

    @Override
    public Iterator<E> iterator() {
        return new WalkThroughIterator();
    }

    public class WalkThroughIterator implements Iterator<E> {

        // All the iterators of all of the sub-trees that weren't null.
        List<Iterator<E>> iterators = new LinkedList<>();
        // Have we delivered the element?
        private boolean deliveredElement = false;

        public WalkThroughIterator() {
            // Is there a 'left' tree?
            if (left != null) {
                iterators.add(left.iterator());
            }
            // a middle
            if (middle != null) {
                iterators.add(middle.iterator());
            }
            // a right
            if (right != null) {
                iterators.add(right.iterator());
            }
        }

        @Override
        public boolean hasNext() {
            // we've finished if we've delivered the element.
            return !deliveredElement;
        }

        @Override
        public E next() {
            // First consume the iterators.
            while (iterators.size() > 0) {
                // Grab the first one.
                Iterator<E> it = iterators.get(0);
                // Has it got an entry?
                if (it.hasNext()) {
                    // Return it's next.
                    return it.next();
                } else {
                    // It's exhaused - remove it.
                    iterators.remove(it);
                }
            }
            // We now deliver our element.
            deliveredElement = true;
            return value;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException("remove() is not supported.");
        }

    }

}

public void test() {
    TernaerTree<String> baum = new TernaerTree<String>(new TernaerTree<String>(null, null, null, "Hallo"), new TernaerTree<String>(null, null, null, "Welt"), new TernaerTree<String>(null, null, null, "?"), "!");
    for (String s : baum) {
        System.out.println(s);
    }
}

我有一种感觉,你已经描述了你的要求是错误的,因为我希望这个元素在right分支之前出现但是可以修复。

答案 1 :(得分:1)

我建议您让TernaerTree实现可迭代。这会让事情变得更容易。您可以在迭代器()中返回WalkThroughIterator迭代器,您将为迭代实现该迭代器。那样的混乱就少了。

然后,您可以将树的所有基本功能作为TernaerTree的一部分。

答案 2 :(得分:1)

最简单的方法(如果你不太关心复杂性/性能),你可以添加一个构造函数,并按照你想要的顺序构建一个线性AST(例如,列表)。

public class WalkThroughIterator implements Iterator {

    private List<E> values = new ArrayList<E>();
    private int currentElement = 0;

    public WalkThroughIterator(TernaerTree<E> tree) {
        buildList(tree);
    }

    private void buildList(TernaerTree<E> node) {

        if (node == null)
            return;

        buildList(node.left); //probably be best to add a getLeft() method etc
        buildList(node.middle);
        buildList(node.right);
        values.add(node.getValue());
    }

    @Override
    public boolean hasNext() {
        return (currentElement < values.size());
    }

    @Override
    public Object next() {
        return values.get(currentElement++);
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("remove() is not supported.");
    }

}

然后只需将getIterator方法添加到树对象中:

public WalkThroughIterator getIterator() {
       return new WalkThroughIterator(this);
}

或者只是在任何地方用root实例化一个新的WalkThroughIterator对象。

(顺便说一句,请注意,如果您有对象实现Iterable,然后按照上面的建议实现,您可以使用for-each循环遍历树。)