是否有解决二叉树问题的“策略”?

时间:2013-08-22 02:52:47

标签: java binary-tree

我希望这是一个可以接受的问题。我理解递归的思维方式,我想要考虑基本情况然后是递归情况,但是考虑到一些比较困难的BST问题,我只是画空白而且感觉就像我迷失方向而没有一个好的方向。

以链接列表为例,似乎有一种模式可以解决问题,但BT似乎要么你知道也要不知道。任何提示/指针?我似乎唯一得到的概念是,如果我正在处理空节点并且我想对它们或它们做些什么,我会把它作为一个案例

if(root == null)
     //do something

或者如果我与null节点没有任何关系,那么我使用反转的基本情况

if(root != null)
     //do stuff
else 
     //do nothing for null case

但即使这样,我也会在接下来的事情上感到茫然。我想这是一个我遇到的问题的例子,不知道如何处理。我不一定在寻找答案,只是处理这类问题的潜在策略(以及常规的二叉树问题)。


编写方法numberNodes,更改存储在二叉树中的数据,为每个节点分配以1开头的顺序整数,以便预订遍历将按顺序生成数字(1,2,3,等等。)。例如,给定左下方树引用的树,tree.numberNodes();的调用将覆盖从1到6分配节点值的现有数据,以便树的预先遍历将产生{{1} }。

您不应更改树的结构。您只是更改存储在数据字段中的值。您的方法应该返回树中有多少节点的计数。

假设您要将此方法添加到1, 2, 3, 4, 5, 6类中,如下所示:

IntTree

在盯着代码后,我想我应该使用我的 public class IntTree { private IntTreeNode overallRoot; ... } 作为一种方法来确定我是否前往左根或右根,因为它是一个二叉搜索树,但我仍然无法实现这个功能......啊!编码块!

4 个答案:

答案 0 :(得分:9)

在考虑使用二叉树进行递归时,基本情况是一个空树,因此您就在那里。另一个关键的概念元素是根据根,左子树和右子树(其中任何一个可能为空)进行思考。

所以我会像这样打破你的样本问题:

  • 如果树是空的,那就无所事事
  • 否则,将下一个号码分配给根(Aha! - 我需要将“下一个号码”传递给此方法。)
  • 递归左侧子树,传递的数量超过当前数字。
  • 递归正确的子树,传递。 。 。啊。我需要知道在处理左子树之后下一个数字是什么。因此,我需要调用左子树来返回下一个数字(比分配的最后一个数字多一个)。这意味着我最好做同样的事情。这将是在右子树上递归后返回的数字。
  • 当我在根节点上调用此方法时,它将在设置所有值后返回下一个可用的数字。设置的节点数量将比此少一个。
  • 实际上,最好只返回最后使用的号码,而不是下一个可用的号码。然后我不需要单独的函数只是从结果中减去一个。所以我最好修改之前的分析,并说要传递给方法的数字(以及返回的数字)应该是最后使用的数字(而不是下一个可用的数字)并相应地调整所有处理。

有了这个,你几乎有了方法的大纲。这是我写它的方式:

public class IntTree {
    private IntTreeNode overallRoot;

    public int numberNodes() {
        return numberNodes(overallRoot, 0);
    }

    /** Helper function */
    private static int numberNodes(IntTreeNode node, int n) {
        if (node != null) {
            node.data = ++n; // preorder means we assign to node first
            n = numberNodes(node.left, n);
            n = numberNodes(node.right, n);
        }
        return n;
    }
}

答案 1 :(得分:2)

通常 - 绘制出来,编写Node类并完成您需要做的事情

在这种情况下,有几个步骤,您需要对其进行逆向工程。

  1. 弄清楚什么是前序遍历

  2. 绘制树并用正确的数字标记每个节点,以便预订将返回他们需要的内容。

  3. 完成您需要做的事情,更容易使用3节点树并进行扩展。

  4. E.g

       1
      / \ 
     2   3
    

    这就是你需要的

    所以你可以看到粗略的想法是

    Given X
    
      Set node.value = X
      X = Call on Left with X + 1    # add null check
      X = Call on Right with X + 1   # add null check
      return X
    

    并且您的numberMethod()将是一个包装器,它在检查空根后检查X = 1的根节点上的上述函数。

答案 2 :(得分:2)

首先,没有空节点。可以为null的是rightleft指针/引用。

第二,有许多不同类型的二叉树。我的意思是基本上不同。这就是为什么你没有看到太多共性的原因之一。

public class BTNode {
    int value;
    BTNode left;
    BTNode right;
}

public static int enumerate(BTNode startNode,int startNumber) {
    int currentNumber= startNumber ;
    if( startNode == null ) return currentNumber ;
    startNode.value= currentNumber ;    // also currentNumber++ and delete next instruction
    currentNumber++;
    currentNumber= enumerate(startNode.left,currentNumber) ;
    currentNumber= enumerate(startNode.right,currentNumber) ;    //  also together with return
    return currentNumber ;
}

计数与节点的值无关。这只与他们的立场有关。无论是右边还是左边都是重要的。

答案 3 :(得分:0)

由于我不太了解Java。对于任何寻求CPP实施的人,我都曾尝试过,它在许多测试用例中都能奏效。

这是我的CPP实施方式

struct Node{
      int data;
      Node* left, *right;
}
    
int NumberNodes(Node *root){
       
      if(root == NULL)
              return 0;
      
      if(root -> left != NULL)
              root -> left -> data = root -> data + 1;
      int l = NumberNodes(root -> left);

      if(root -> right != NULL)
              root -> right -> data = max(root->data, l) + 1;
      int r = NumberNodes(root -> right);

      return max(l, max(r, root->data));
}

int main(){
      Node *root = new Node();    //Or provide the root of your    ///  binary tree as mentioned in problem. 
      root->data = 1;
      int count = NumberNodes(root);  // count has the number of nodes in tree. 
}