如何在深度优先预购中为二叉树实现惰性迭代器

问题描述

我需要为二叉树实现一个惰性迭代器,以便它以“深度优先”的顺序遍历该树。

我甚至在努力考虑要这样做的可靠策略。

这是我到目前为止的内容,但是我不确定这是否是正确的方法。

package LazyTreeIterator;


import java.util.*;

/**
 * Iterates lazily over a binary tree in a depth-first manner. For instance a tree
 * with 8 as it's root and 4 and 10 as it's children should be iterated as: 8 ->
 * 4 -> 10.
 */
public class BinaryTreeIterator<V> implements Iterator<V> {

    private BTree<V> tree;
    private ArrayList<Position<V>> visited;
    private Position<V> currentPointer;
    private Stack<Position<V>> roots;
    private Stack<Position<V>> rightNodes;
    private Stack<Position<V>> leftNodes;


    /**
     * Constructor.
     * Should reset on a new tree.
     *
     * @param tree
     *     takes the tree
     */
    public BinaryTreeIterator(BTree<V> tree) {
        this.tree = tree;
        this.visited = new ArrayList<>();
        this.currentPointer = tree.getRoot();
        this.roots = new Stack<>();
        this.roots.add(currentPointer); //Put the root of the tree into the known roots stack.
        this.rightNodes = new Stack<>();
        this.leftNodes = new Stack<>();
        PushChildrenToStack(currentPointer); //Add the children of the root to their stacks
    }

    /**
     * @return True if there is a next element in the iterator,else False
     */
    @Override
    public boolean hasNext() {

        return true;
    }

    /**
     * Get the next element of the iterator and shift
     * iterator by one.
     *
     * @return current element value
     * @post iterator is moved to next element
     */
    @Override
    public V next() {
        if (!leftNodes.isEmpty() && !HasBeenVisited(leftNodes.peek())){
            return MoveToLeftNodeAndGetCurrent().getValue();
        }
        else if (!rightNodes.isEmpty() && !HasBeenVisited(rightNodes.peek())){
            //return MoveToRightSubTree();
        }
        return null;
    }


    /**
     * Adds the direct children of the passed node to the corresponding stacks.
     * @param parent
     */
    private void PushChildrenToStack(Position<V> parent){
        try{
            if (tree.hasRight(parent)){
                rightNodes.add(tree.getRight(parent));
            }
            if (tree.hasLeft(parent)){
                leftNodes.add(tree.getLeft(parent));
            }
        }catch(InvalidPositionException e){
            System.out.println(e.toString());
        }
    }

    private boolean HasDirectChildren(Position<V> parent){
        try{
            return (tree.hasLeft(parent) || tree.hasRight(parent));
        } catch(InvalidPositionException e){
            System.out.println(e.toString());
            return false;
        }
    }


    private boolean HasBeenVisited(Position<V> node){
        return visited.contains(node);
    }

    private Position<V> MoveToLeftNodeAndGetCurrent(){
        try {
            //Store the currentPointer so we can return it later on.
            Position<V> temp = currentPointer;

            //Retrieve the next left node,because we already know it exists,it it is now the currentPointer
            currentPointer = leftNodes.pop();

            //Make life easier: Store information on this newNode to the corresponding stacks
            if (HasDirectChildren(currentPointer)){
                roots.add(currentPointer);           //Register this node as root of a subtree
                PushChildrenToStack(currentPointer); //Save the children to their stacks so we can track back later
            }//If the new current node has no children at all
            else if (!HasDirectChildren(currentPointer)){
                // Then the current one has to go to either the sibling,or the nod is on the right according to most logical point.
                System.out.println("In deze gare gedoe");
                if (HasSiblingOnTheRight(currentPointer)){
                    return MoveCurrentToSiblingOnTheRightAndGetCurrent();
                }else{
                    //Go back up one level aka go back to its direct parent.

                };

            }

            //Register the fact that we have visiting the old value of currentPointer and are about to return it
            visited.add(temp);
            return temp;


        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public boolean HasSiblingOnTheRight(Position<V> node){
        Position<V> parent = roots.peek();
        try{
            if (tree.hasRight(parent)){
                return true;
            }
            else{return false;}
        } catch (InvalidPositionException e){
            System.out.println(e.toString());
            return false;
        }
    }

    public Position<V> MoveCurrentToSiblingOnTheRightAndGetCurrent(){
        Position<V> parent = roots.peek();
        try{
            Position<V> temp = currentPointer;
            currentPointer = tree.getRight(parent);
            //Make life easier again and try to store its information unto the stack\
            if (HasDirectChildren(currentPointer)){
                roots.add(currentPointer);           //Register this node as root of a subtree
                PushChildrenToStack(currentPointer); //Save the children to their stacks so we can track back later
            }
            return temp;
        } catch (InvalidPositionException e){
            System.out.println(e.toString());
            return null;
        }
    }



    /**
     * Skip a single element of the iterator.
     *
     * @post iterator is moved to next element.
     */
    @Override
    public void remove() {
        // TODO

    }
}

我在这里想要做的是将根放在堆栈中,并将其左,右子级直接添加到自己的堆栈中。然后,我尝试转到左侧的子节点,将指针更改为该子节点,然后返回其上方的节点。我一直向左走直到它不再可能为止,因为最左边的假期到了。

只要一个节点没有子节点,它就会尝试将指针设置为其兄弟节点(如果存在兄弟节点)。如果未找到同级,我打算使用称为roots的堆栈返回上一级,并在尚未访问其子级的情况下尝试转到一个子级(例如,如果未出现在访问列表中的节点,则未访问过该节点) )。如果已经访问了该节点的孩子,那么我将再上一层,并尝试执行相同的操作,直到进入尚未访问过孩子的节点为止。

此过程有意义吗?有什么更有效的方法我想念吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...