简体   繁体   English

在Java中编辑二叉树中的节点

[英]Edit the nodes in a binary tree in Java

Okay. 好的。 I have a binary tree, and this is what I want to do with it: 我有一棵二叉树,这就是我要使用的二叉树:

For each node in original tree: If it's not a leaf, replace it with a leaf node. 对于原始树中的每个节点:如果不是叶子,则将其替换为叶子节点。 Do a calculation on the original tree updated with the removed branch. 对用删除的分支更新的原始树进行计算。 Revert the node back to how it was (so now the tree is the same as at the beginning). 将节点恢复为原来的状态(因此,树与开始时的树相同)。

The problem is this: I am traversing the tree using a stack. 问题是这样的:我正在使用堆栈遍历树。 If I change the stack.pop() node to a leaf, this does NOT remove any branches in the original tree. 如果我将stack.pop()节点更改为叶子,则不会删除原始树中的任何分支。 It's the same reasoning behind why you can do: 您可以这样做的原因也是相同的:

int x=1
int y=x
y++

And x still equals 1. There's a technical term for this but I forgot it. x仍然等于1。有一个技术术语,但我忘记了。

So how can I edit the nodes in an original tree and still traverse it? 那么,如何编辑原始树中的节点并仍然遍历它呢?

This is basically what I'm doing to traverse the tree right now: 这基本上是我现在正在遍历树的工作:

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

From what I can tell from your question, for every Node you want to calculate something about the tree as if that node was a leaf. 根据您的问题,我可以说出的是,对于每个Node您都想要计算有关树的某些内容,就好像该节点是叶子一样。

To do this there is no reason to actually make that node a leaf and then reattach it. 为此,没有理由使该节点真正成为叶子,然后重新附加它。 Instead, your logic can simply remember which node to treat as a leaf for each computation. 取而代之的是,您的逻辑可以简单地记住每次计算将哪个节点视为叶子。

Traverse the tree, and for each Node , let's call it outerCurrentNode , once again traverse the tree doing your calculation - but now for each Node , let's call it innerCurrentNode , test to see if outerCurrentNode == innerCurrentNode . 遍历树,对于每个Node ,我们将其outerCurrentNode ,再次遍历树进行计算-但现在,对于每个Node ,我们将其innerCurrentNode ,测试一下是否看到outerCurrentNode == innerCurrentNode If the test returns true , treat that innerCurrentNode as if it's a leaf, ignoring its children. 如果测试返回trueinnerCurrentNode视为叶子,而忽略其子级。

EDIT: Here's a mock up of what I'm suggesting (untested): 编辑:这是我建议的模型(未经测试):

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

I'm using recursion instead of a Stack , but either will work. 我正在使用递归而不是Stack ,但是任何一种都可以。 iterativePreorder() does a traversal, calling doCalculation() for each Node , passing it in along with the root (to keep track of the entire tree). iterativePreorder()进行遍历,为每个Node调用doCalculation() ,并将其与根一起传递(以跟踪整个树)。 That method then does its own traversal, doing your calculation, but stopping short when it reaches the specially marked Node . 然后,该方法自己进行遍历,进行计算,但是在到达特别标记的Node时停止运行。

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

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