算法遍历整个树结构

时间:2013-05-15 13:42:17

标签: java algorithm tree-traversal

Class Diagnostic {

//Get the size in bytes of an object
static long sizeOf(Object object);

//Get the references for an object (leafs)
static List<Object> getRefs(Object object);

//Implement this with those above
public Long objectSize(Object object);
}

如何实现objectSize以返回对象的字节大小?

方法objectSize返回组合的所有子节点(树上的每个节点)的字节大小。

示例:

               Object A (19 bytes)
                      /    \
                     /      \
                   B(20)    C(37)
                   /
                  /
                C(15)

答案:19 + 20 + 37 + 15 = 91

我在接受采访时遇到了这个问题,我非常好奇地看到别人的答案。因为,我对树遍历算法知之甚少。

我想出了这个......(我知道这是坏事与否;),只是想学习)

    public Long objectSize(Object object) {
    List<Object> objectList = new ArrayList<Object>();

    Long sum = sizeOf(object);
    objectList = getRefs(object);

    for(Object object : objectList){
           sum += objectSize(object);
    }

return sum;
}

我注意到我可以有一个循环并运行stackoverflow错误,因为我没有检查我是否已经通过“节点”。然后我很难,我应该有另一个数据结构(如处理键/值的散列图)来处理临时列表以进行比较。

3 个答案:

答案 0 :(得分:2)

如果你正在处理一个真正的“树”结构,那么你不必担心周期。

你有基本的想法,但你需要考虑递归调用的实际返回值。如果我们假设对象的总大小(objectSize())等于其子项大小加上其自身大小(sizeOf())的总和,那么您只需要确保添加所有子树大小一起。

这是你可以做到的一种方式:

public Long objectSize(Object object) {
    List<Object> objectList = getRefs(object);
    long sum = sizeOf(object);

    for(Object object : objectList) {
         sum += objectSize(object);
    }

    return Long.valueOf(sum);
}

您遗失的是递归objectSize调用返回了一个值,并且该值需要包含在(在这种情况下通过添加)到您的返回值中。

答案 1 :(得分:0)

我没有测试它,但这个简单的BFS搜索算法应该这样做。

public Long objectSize(Object object) {
   long sum=sizeOf(object);

   Queue<Object> q= new LinkedList<Object>();
   for (Object o : getRefs(object)) {
      q.add(o);
   }
   while (q.peek() != null) {
      Object child= q.poll();
      sum+= sizeOf(child);
      fore (Object o : getRefs(child)) {
         q.add(o);
      }
   }
   return sum;   
}

答案 2 :(得分:0)

以下是我要做的事情:

我会构建一个包含剩余待探索节点的堆栈,并在 while 循环中处理它。由于我的Java技能在我的脑海中遗失了,我不会给你一个实现,但我将解释这个过程:

输入 T
输出:节点对象的总大小

  1. 通过将 T.root (根节点)推入其中来初始化堆栈 S
  2. 将总尺寸尺寸初始化为0:尺寸 = 0
  3. 虽然 S 不为空:
    1. N 成为 S 的负责人,我们弹出 S N = pop(小号
    2. N.leftChild N.rightChild 推送到 S (如果存在)
    3. 更新尺寸尺寸 = 尺寸 + N.size
  4. 返回尺寸