我如何编写迭代器以“按顺序”方式迭代二叉树的每个值?我应该使用堆栈。 BinaryNode是一个简单的节点类,其指针指向“左”和“右”节点。以下是我到目前为止的情况:
class InOrderIterator implements Iterator<T> {
private Stack<BinaryNode> stack;
public InOrderIterator(BinarySearchTree<T>.BinaryNode root) {
stack = new Stack<BinaryNode>();
stack.push(root);
}
@Override
public boolean hasNext() {
while (!this.stack.isEmpty() && stack.peek() == NULL_NODE)
this.stack.pop();
return !this.stack.isEmpty();
}
@Override
public T next() {
//TODO
if (!this.hasNext())
throw new NoSuchElementException("No more nodes in tree!");
BinaryNode current = this.stack.pop();
BinaryNode output = null;
while(current != NULL_NODE){
this.stack.push(current);
current = current.left;
}
if(current == NULL_NODE){
if(!this.stack.isEmpty()){
output = this.stack.pop();
return output.data;
}
}
return null;
}
}
我有基本算法,但我似乎无法将其转换为java代码。
答案 0 :(得分:1)
考虑不变量。你有一堆节点。节点在堆栈上意味着什么?
我可以建议:堆栈上的节点代表一个“半树”,一个节点及其整个右子树,并且堆栈包含所有半树,这些半树一起组成所有尚未返回的节点next()呢。
这些半树应该以什么顺序被推到堆叠上?回答这个问题可以为您提供不变条件,即在代码运行时保留的属性。
让自己相信你的不变量意味着堆栈顶部必须是next()接下来要返回的东西。当你弹出它以返回它时,你将不得不在返回之前以某种方式处理它的右子树。从你的不变量来看,应该明白如何做到这一点。
如果你没有有意识地明确地思考你的变量意味着什么以及你的不变量是什么,那么你的编码工作将是无向的。你会四处寻找意大利面条代码。但是,一旦你完成了,代码就会自行编写。
答案 1 :(得分:-1)
public class BinaryTreeNode {
private int element; //element stored at this node
private BinaryTreeNode left, right;
public BinaryTreeNode() { }
public BinaryTreeNode(int element) {
setElement(element);
setLeft(null);
setRight(null);
}
//returns the elements stored at this position
public int element() {
return element;
}
//sets the elements stored at this position
public void setElement(int e) {
element = e;
}
//return the left child of this position
public BinaryTreeNode getLeft() {
return left;
}
//set the left chid of this position
public void setLeft(BinaryTreeNode l) {
left = l;
}
//return the right child of this position
public BinaryTreeNode getRight() {
return right;
}
//sets the right child of this position
public void setRight(BinaryTreeNode r) {
right = r;
}
}
public class TestBTN {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
BinaryTreeNode root = null, right, left, node = null;
int arrayInt[] = {25, 20, 7, 13, 33, 50, 45, 17, 30, 55};
for (int i = 0; i < arrayInt.length; i++) {
if (root == null) {
root = node = new BinaryTreeNode(arrayInt[0]);
}//endIf
else {
node = new BinaryTreeNode(arrayInt[i]);
BinaryTreeNode s, p;
p = s = root;
while (s != null) {
p = s;
if (node.element() > s.element()) {
s = s.getRight();
} else {
s = s.getLeft();
}
}//endWhile
if (node.element() > p.element()) {
p.setRight(node);
} else {
p.setLeft(node);
}
}//emdElse
}//endFor
//printing
//Print(root);
//PostOrder(root);
//PreOrder(root);
InOrder(root);
//System.out.println("\nBinaryTreeNode");
}//endMain
private static void Print(BinaryTreeNode node) {
if (node != null) {
System.out.print(node.element() + " ");
Print(node.getLeft());
Print(node.getRight());
}//endIf
}//endPrint
static void PostOrder(BinaryTreeNode ptr) {
if(ptr != null) {
PostOrder(ptr.getLeft());
PostOrder(ptr.getRight());
System.out.print(ptr.element()+" ");
}//endIf
}//endPost
static void PreOrder(BinaryTreeNode ptr) {
if(ptr != null) {
System.out.print(ptr.element()+" ");
PreOrder(ptr.getLeft());
PreOrder(ptr.getRight());
}
}
static void InOrder(BinaryTreeNode ptr) {
if(ptr != null) {
InOrder(ptr.getLeft());
System.out.print(ptr.element()+" ");
InOrder(ptr.getRight());
}
}
}