繁体   English   中英

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

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

好的。 我有一棵二叉树,这就是我要使用的二叉树:

对于原始树中的每个节点:如果不是叶子,则将其替换为叶子节点。 对用删除的分支更新的原始树进行计算。 将节点恢复为原来的状态(因此,树与开始时的树相同)。

问题是这样的:我正在使用堆栈遍历树。 如果我将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
        }
}

根据您的问题,我可以说出的是,对于每个Node您都想要计算有关树的某些内容,就好像该节点是叶子一样。

为此,没有理由使该节点真正成为叶子,然后重新附加它。 取而代之的是,您的逻辑可以简单地记住每次计算将哪个节点视为叶子。

遍历树,对于每个Node ,我们将其outerCurrentNode ,再次遍历树进行计算-但现在,对于每个Node ,我们将其innerCurrentNode ,测试一下是否看到outerCurrentNode == innerCurrentNode 如果测试返回trueinnerCurrentNode视为叶子,而忽略其子级。

编辑:这是我建议的模型(未经测试):

//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()进行遍历,为每个Node调用doCalculation() ,并将其与根一起传递(以跟踪整个树)。 然后,该方法自己进行遍历,进行计算,但是在到达特别标记的Node时停止运行。

暂无
暂无

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

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