【问题标题】:Uniquely number nodes of a Binary Tree二叉树的唯一编号节点
【发布时间】:2015-08-14 16:38:28
【问题描述】:

生成二叉树后如何为每个节点设置索引?

      (a)               (1)
   (x)   (r)   =>     (2)  (3)
  (o)(t)(t)(x)      (4)(5)(6)(7) 

然后我可以在特定节点上使用诸如getIndex()之类的调用来返回其索引。

我的树类:

public class BT<E>{
   E value;
   BT<E> left, right;
   int Index;

   public BT(E value)
   {
      this.value=value;
   }   

   public BT (E value, BT left, BT right) 
   {
      this.value = value;
      this.left = left;
      this.right = right;
   }

【问题讨论】:

  • 您是否可以在完全创建树后再次遍历它,或者您是否尝试在创建树的第一次遍历中初始化此索引?
  • 简单地逐层遍历你的树。
  • @NoseKnowsAll 我需要在树完全创建后完成。
  • 可以利用层序遍历。

标签: java recursion tree binary-tree


【解决方案1】:

广度优先遍历。

Queue<BT> queue = new LinkedList<BT>() ;

public void breadth(BT root) {
    if (root == null)
        return;

    queue.clear();
    queue.add(root);
    int index = 0;
    while(!queue.isEmpty()){
        BT node = queue.remove();
        node.Index = index;
        index++;
        if(node.left != null) queue.add(node.left);
        if(node.right != null) queue.add(node.right);
    }

}

改编自here

【讨论】:

    【解决方案2】:

    如果您在完全创建树后执行此操作,则使用级别顺序遍历的方法将起作用。它不是非常有效,但它是直接递归:

    /* Method to set index based on level-order traversal of tree */
    public void initIndices(BT root) {
        int maxIndexSoFar = 0;
        for (int d = 1; d <= root.height(); ++d)
            maxIndexSoFar = setIndexAtLevel(root, d, maxIndexSoFar);
    }
    
    /* Method to set index of all nodes at a given level */
    private int setIndexAtLevel(BT node, int level, int index) {
        if (tree == null)
            return index;
        if (level == 1) {
            index++;
            node.setIndex(index);
            return index;
        }
        else if (level > 1) {
            int newIndex = setIndexAtLevel(node.left, level-1, index);
            newIndex = setIndexAtLevel(node.right, level-1, newIndex);
            return newIndex;
        }
        return -1;
    }
    

    我会让你创建height() 方法和setIndex() 方法。公平警告,我根本没有测试过,所以请原谅任何错别字。

    【讨论】:

      【解决方案3】:

      所以你要实现一个过程getIndex(int index),它必须返回具有该索引的节点?

      如果是这样,您正在寻找一种表示二叉树的有效方法。 您可以为每次调用 getIndex 遍历树,但这不会有效...

      一个有效的解决方案是将完整二叉树存储在一个数组中,因为它提供了 O(1) 访问。将节点 n 存储在数组中的索引 n 处,并将其子节点存储在索引 2*n(2*n) - 1 处。但是这里的限制是树必须是完整的,并且数组的大小是不可变的(如果二叉树变得太大,应该制作一个更大的数组(通常是两倍大)并且应该复制所有元素)。

      这是一个方便的解决方案,因为:

      • 节点访问在 O(1) 中,但像 addNode() 这样的过程将在 O(1) 中摊销(*)
      • 节点不必记住它的子节点 --> this.left 变为 this.left(),下面提供了 left() 的实现。

      left() 过程的可能实现。

      static int[] binaryTreeArray = new int[maxTreeSize]; // BT of integers for example
      ...
      public int left() { // returns integer or ... (type of your nodes)
          return binaryTreeArray[(this.Index)*2]; // O(1)
      }
      

      (*) 类似addNode() 的过程大多数时候会在 O(1) (binaryTreeArray[index] = nodeValue;) 中添加节点,但是当 binaryTreeArray 已满时,它必须一个更大的数组,通常是两倍大(复制的 O(n))。可以证明,这具有 O(1) 的摊销成本,但这对这个答案没有附加价值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-25
        • 2012-04-15
        • 2010-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多