【问题标题】:Tree traversal in JavaJava中的树遍历
【发布时间】:2012-02-01 20:25:52
【问题描述】:

我正在为求职面试而学习并正在审查树木,我在遍历它们时没有问题,但我遇到了一个我无法找到正确答案的问题:

编写一个函数,在给定两个参数的情况下返回树中的一个节点: 指向根节点的指针和节点的中序遍历数 我们想回来。树中存储的唯一信息是 每个节点的子节点数。

到目前为止,我什至无法弄清楚为什么我会关心存储在树中的信息(孩子的数量)。除此之外,如果我们假设有一棵像这样的树:

     5
  4     7
3  1  4

那么中序遍历将是341547,但我无法弄清楚返回我想要的节点的代码(为了论证,我假设中序遍历数是 2 - 这意味着我想要值的节点1).

我尝试进行递归遍历,但最终搞砸了我拥有的内部计数器,因此我尝试了一种不同的方法,只是尝试将所有内容放在堆栈上,但我不知道如何正确地这样做。到目前为止,我有:

public int findNode(root, position){
   Stack<Integer> s = new Stack<Integer>();
   cNode = root; //cNode = current Node

   while(cNode.left != null)
      cNode = cNode.left;

     s.push(cNode);

   while(cNode.right != null)
     cNode = cNode.right;

   //stuck here.
}

递归方法更简单,但我不知道如何检查我是否有 # 我正在寻找:

public int findNode(root, position){
    cNode = root;   
    if(cNode != null){ 
       findNode(cNode.left, position);
       System.out.print(cNode.data);
       findNode(cNode.right, position);
   }
}

我知道这会遍历树,但它仍然不能完全满足我的要求。任何帮助将不胜感激。

【问题讨论】:

  • 鉴于“存储在树中的唯一信息是每个节点的子节点数”,我猜你的示例树是错误的。另外,“中序遍历数”究竟是什么?
  • "编写一个函数,返回树中的一个节点给定两个参数",树中的一个节点,哪个节点?具有该特定值的节点或在该特定索引处的节点(索引为中序遍历)???

标签: java binary-tree tree-traversal


【解决方案1】:

你可以这样做:

public Node findNode(Node root, int position) {
    ArrayList<Node> a = new ArrayList<Node>();
    populateNodes(root, a);
    return a.get(position);
}

private void populateNodes(Node node, ArrayList<Node> a) {
    if (node == null) return;
    populateNodes(node.left, a);
    a.add(node);
    populateNodes(node.right, a);
}

注意:如果你不想要,你不需要使用额外的数据结构,但是因为你有一个 Stack,所以我就用它了。

注意 2:正如 Jim Garrison 指出的,如果您有后代计数,您可以优化算法。

【讨论】:

  • 这太棒了,我不知道我怎么想不到这个,非常感谢。
【解决方案2】:

这个问题模棱两可。 “中序”对于二叉树是有意义的,在这种情况下,“孩子的数量”总是两个,除非它们的意思是“后代的数量”,在这种情况下,您可以使用它来避免通过中序列表进行线性搜索(O * n) 因为在每个节点上,您可以根据后代的数量决定采用哪个分支 (O*log n)。

【讨论】:

  • 我猜这棵树是错的,错过了一个孩子。因为那是我在书中的例子。
  • 你说的“想念一个孩子”是什么意思。二叉树不必完全填满。
【解决方案3】:

不是传递位置,而是传递中序遍历数并在每个递归方法中附加到它。

【讨论】:

    【解决方案4】:

    最好利用树的属性来降低算法的复杂度,即每个节点都知道它拥有的子节点总数。因此,如果您知道当前节点左侧有多少个子节点,则可以计算当前节点的订单号(对于根,它将是左侧的子节点数 + 1)以下代码应该可以工作:

    Nodeptr nthInInorder(Nodeptr root, int x){
     Nodeptr curr = root;
     int countedIn = 0, leftchildren = 0, currIn=0;
    
     while(curr!=NULL){
      if(curr->left == NULL)
       leftchildren = 0;
      else
       leftchildren = (curr->left)->data + 1;
    
      currIn = countedIn + leftchildren + 1;
    
      if(currIn == x)
       return curr;
      else if(currIn > x)
       curr = curr->left;
      else if(currIn < x)
       { countedIn = currIn + 1;
         curr = curr->right;
       }
      }
      return NULL;
     }
    

    这个算法的复杂度是O(log n)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多