用Java编辑二叉树中的节点

时间:2011-09-22 02:55:58

标签: java binary-tree traversal tree-traversal

好。我有一个二叉树,这就是我想用它做的事情:

对于原始树中的每个节点:  如果它不是叶子,请用叶子节点替换它。  使用已删除的分支更新原始树上的计算。  将节点恢复为原样(现在树与开头的树相同)。

问题是:我正在使用堆栈遍历树。如果我将stack.pop()节点更改为叶子,则不会删除原始树中的任何分支。这就是为什么你可以这样做的原因:

int x=1
int y=x
y++

x仍然等于1.这是一个技术术语,但我忘了它。

那么如何编辑原始树中的节点并仍然遍历它呢?

这基本上就是我现在要遍历树的方式:

public void iterativePreorder(Node root) {
        Stack nodes = new Stack();
        nodes.push(root);

        Node currentNode;

        while (!nodes.isEmpty()) {
                currentNode = nodes.pop();
                Node right = currentNode.right();
                if (right != null) {
                        nodes.push(right);
                }
                Node left = currentNode.left();
                if (left != null) {
                        nodes.push(left);      
                }
                //This is where you do operations on the currentNode
        }
}

1 个答案:

答案 0 :(得分:0)

从我的问题可以看出,对于每个Node,你想要计算一些关于树的东西,好像那个节点是叶子一样。

要做到这一点,没有理由让该节点成为叶子,然后重新附加它。相反,您的逻辑可以简单地记住将哪个节点视为每个计算的叶子。

遍历树,对于每个Node,我们称之为outerCurrentNode,再次遍历树进行计算 - 但现在对于每个Node,我们称之为{{1} },测试看看innerCurrentNode。如果测试返回outerCurrentNode == innerCurrentNode,请将true视为叶子,忽略其子项。

编辑:以下是我建议(未经测试)的模拟:

innerCurrentNode

我正在使用递归而不是//entry point - called from directing code public void iterativePreorder(Node root) { iterativePreorderKernel(root, root); } //recursive method - keeps track of root in addition to current Node private void iterativePreorderKernel(Node root, Node current) { if (current.left() != null) { iterativePreorderKernel(root, current.left()); } if (current.right() != null) { iterativePreorderKernel(root, current.right()); } //for each Node in the tree, do calculations on the entire tree, pretending //the current Node is a leaf doCalculation(root, current); } //calculation method (also recursive) - takes a current Node, plus //the Node to treat as a leaf public void doCalculation(Node innerCurrent, Node pretendLeaf) { //do calculation with inner current node if (innerCurrent != pretendLeaf) { if (innerCurrent.left() != null) { doCalculation(innerCurrent.left(), pretendLeaf); } if (innerCurrent.right() != null) { doCalculation(innerCurrent.right(), pretendLeaf); } } } ,但两者都可以。 Stack执行遍历,为每个iterativePreorder()调用doCalculation(),将其与根一起传递(以跟踪整个树)。然后该方法进行自己的遍历,进行计算,但在到达特别标记的Node时停止。