问题描述
我需要为二叉树实现一个惰性迭代器,以便它以“深度优先”的顺序遍历该树。
我甚至在努力考虑要这样做的可靠策略。
这是我到目前为止的内容,但是我不确定这是否是正确的方法。
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 (将#修改为@)