简体   繁体   English

二叉树:有序迭代器:Java

[英]Binary Trees: In-order Iterator: Java

How would I go about writing an iterator to iterate over each value of a binary tree in "in-order" fashion? 我将如何编写迭代器以“有序”方式遍历二叉树的每个值? I should be using a stack. 我应该使用堆栈。 BinaryNode is a simple node class with pointers to "left" and "right" nodes. BinaryNode是一个简单的节点类,带有指向“左”和“右”节点的指针。 Here is what I have so far: 这是我到目前为止的内容:

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;
    }
}

I have the basic algorithm down, but I can't seem to convert it to java code. 我已经掌握了基本算法,但是似乎无法将其转换为Java代码。

Think about invariants. 考虑不变式。 You have a stack of nodes. 您有一堆节点。 What does it mean for a node to be on the stack? 节点在堆栈上意味着什么?

Might I suggest: A node on the stack represents a "half-tree", a node and its entire right subtree, and the stack holds all the half-trees that together make up all the nodes that have not been returned from next() yet. 我可能建议:堆栈上的一个节点代表一个“半树”,一个节点及其整个右子树,并且堆栈保存所有半树,这些半树共同构成了所有未从next()返回的节点。然而。

In what order should those half-trees be pushed on the stack? 这些半树应按什么顺序推入堆栈? Answering that question gives you your invariant condition, the property that will be preserved as your code runs. 回答该问题将为您提供不变的条件,即在代码运行时将保留的属性。

Satisfy yourself that your invariant implies that the top of the stack must be whatever next() is going to return next. 令自己满意的是,您的不变式意味着堆栈的顶部必须是next()将要返回的next。 When you pop it off to return it, you're going to have to somehow deal with its right subtree before returning. 当您弹出它返回它时,您将不得不在返回之前以某种方式处理其正确的子树。 From your invariant, it should be obvious how to do that. 从您的不变性来看,如何做到这一点应该很明显。

If you don't consciously and explicitly think about what your variables mean and what your invariants are, your coding efforts are going to be undirected. 如果您不自觉和明确地考虑变量的含义和不变量是什么,那么您的编码工作将是无方向的。 You're going to flail around, writing spaghetti code. 您将四处乱窜,编写意大利面条代码。 Once you've done that, though, the code will write itself. 但是,一旦完成,代码将自行编写。

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());
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM