通过二叉搜索树迭代查找所有叶子

时间:2012-11-05 19:52:12

标签: java algorithm iterator nodes binary-search-tree

我对树很新,我正在尝试创建一种“叶子迭代器”。我认为它应该将没有.left.right值的所有节点放到堆栈上,但我不确定它是怎么做的,甚至是不对的。我试过搜索它,但是我遇到的每个例子都是从最左边的叶子开始,然后转到p = node.parent,我避免链接到节点的父节点。

我不明白如何重复从根开始并经过葡萄藤而不会一遍又一遍地访问相同的葡萄藤。

修改

我看到人们建议使用递归方法来解决这个问题,我现在同意了。但是我一直在试图寻找迭代器类方法来解决这个问题一段时间,我仍然想知道这是否可行,以及如何实现!

3 个答案:

答案 0 :(得分:15)

使用递归:

public void visitNode(Node node) {
    if(node.left != null) {
        visitNode(node.left);
    }
    if(node.right != null) {
        visitNode(node.right);
    }
    if(node.left == null && node.right == null) {
        //OMG! leaf!
    }
}

通过提供root来启动它:

visitNode(root);

为了将其转换为Iterator<Node>,您必须将递归转换为循环,然后使用状态进行遍历。非平凡,但应该给你带来很多乐趣。

答案 1 :(得分:3)

class Node {
    public Node left = null;
    public Node right = null;
    // data and other goodies
}
class Tree {
    public Node root = null;
    // add and remove methods, etc.
    public void visitAllLeaves(Node root) {
        // visit all leaves starting at the root
        java.util.Stack<Node> stack = new java.util.Stack<Node>();
        if (root == null) return; // check to make sure we're given a good node
        stack.push(root);
        while (!stack.empty()) {
            root = stack.pop();
            if (root.left == null && root.right == null) {
                // this is a leaf
                // do stuff here
            }
            if (root.left != null) {
                stack.push(root.left);
            }
            if (root.right != null) {
                stack.push(root.right);
            }
        }
    }
}

我不确定上面的代码是否有效,但这是在需要做的事情的某个方面。另一种选择是javax.swing.TreeModel(半开玩笑)。

答案 2 :(得分:1)

以下是如何实现只返回叶节点的Iterator,即没有左子树或右子树的节点。

迭代器通过深度优先搜索来搜索树中的叶节点,记住堆栈中搜索的当前状态并且&#34;暂停&#34;当它找到一个叶子节点时(参见fetchNext()方法)。

当客户&#34;消费&#34>时,搜索将恢复。叶子节点通过调用next()。

class Node {
  public Node left;
  public Node right;
}

class LeaveIterator implements Iterator<Node> {
  private final Stack<Node> stack = new Stack<>();
  private Node nextNode = null;

  public LeaveIterator(Node root) {
    if (root != null) {
      stack.push(root);
      nextNode = fetchNext();
    }
  }

  private void fetchNext() {
    Node next = null;
    while (!stack.isEmpty() && next == null) {
      Node node = stack.pop();
      if (node.left == null && node.right == null) {
        next = node;
      }
      if (node.right != null) {
        stack.push(node.right);
      }
      if (node.left != null) {
        stack.push(node.left);
      }
    }
    return next;
  }

  public boolean hasNext() {
    return nextNode != null;
  }

  public Node next() {
    if (!hasNext()) {
      throw new NoSuchElementException();
    }
    Node n = nextNode;
    nextNode = fetchNext();
    return n;
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }
}