Algorithm 通过二叉树节点的广度优先索引对其进行递归索引

Algorithm 通过二叉树节点的广度优先索引对其进行递归索引,algorithm,recursion,binary-tree,Algorithm,Recursion,Binary Tree,问题是:我需要能够通过索引从高度未知的完美二叉树中递归检索节点 由于未知高度属性,似乎唯一有意义的索引形式是根据标题的宽度优先索引: 0 1 2 3 4 5 6 问题是,在每个节点上,似乎很难知道采取哪个方向,以及如何将递归请求中的索引转换到该子节点。。。或者我只是没有想清楚 Node Navigate(Index): Index 0: return this; Index 1: return Left.Navigat

问题是:我需要能够通过索引从高度未知的完美二叉树中递归检索节点

由于未知高度属性,似乎唯一有意义的索引形式是根据标题的宽度优先索引:

          0
    1           2
3       4   5       6
问题是,在每个节点上,似乎很难知道采取哪个方向,以及如何将递归请求中的索引转换到该子节点。。。或者我只是没有想清楚

Node Navigate(Index):
Index 0: return this;
Index 1: return Left.Navigate(0);
Index 2: return Right.Navigate(0);
Index 3: return Left.Navigate(1);
Index 4: return Left.Navigate(2);
Index 5: return Right.Navigate(1);
Index 6: return Right.Navigate(2);
...
Index 7: return Left.Navigate(3);
Index 8: return Left.Navigate(4);
Index 9: return Left.Navigate(5);
Index 10: return Left.Navigate(6);
Index 11: return Right.Navigate(3);
Index 12: return Right.Navigate(4);
Index 13: return Right.Navigate(5);
Index 14: return Right.Navigate(6);
模式很清楚-但是如何通过编程-不消耗太多的时钟周期-这是一个嵌入式设备-从索引中选择一个节点,并将索引转换为该节点的导航参数?我是否错过了一个简单的转变

以下是我最终使用的实现,基于yurib的答案:

public class Node
{
  public Node Left, Right;

  public Node(int levels)
  {
      if (levels == 0) return;
      Left = new Node(levels - 1);
      Right = new Node(levels - 1);
  }

  public Node Navigate(int index)
  {
      if (index == 0) return this;

      // we want 1 based indexing.
      int oneBased = index + 1;
      // level is how many levels deep we are looking, stored as 1 << depth.
      int level = 1;  
      // find level - it's equal to the highest bit in "oneBased". Find it.
      for (int i = oneBased; (i >>= 1) != 0; )
      {
          level *= 2;
      }

      // level adjusted for our children.
      int subLevel = level >> 1;
      // clear our level bit, set our children's level bit.
      int childIndex = ((oneBased & ~level) | subLevel) - 1;

      // is the node we're looking for over half way through level? go right.
      if ((oneBased & subLevel) != 0)
          return Right.Navigate(childIndex);
      else
          return Left.Navigate(childIndex);  // otherwise it's in our left tree.
  }
}

它是用于测试的C,尽管实际上每个导航调用都是在不同的嵌入式设备上处理的,因此需要递归,而不是简单地遵循伪代码、构建列表等。感谢yurib:。

要找到第n个节点,请遵循通过将n重复除以2并跟踪余数而创建的路径。当1表示右,0表示左时,按照余数创建的路线反向走

例如,要添加第6项索引=5: 6/2 = 3 0 3/2=1


这意味着从根开始向右,向左。

要找到第n个节点,请按照重复将n除以2并跟踪余数所创建的路径。当1表示右,0表示左时,按照余数创建的路线反向走

例如,要添加第6项索引=5: 6/2 = 3 0 3/2=1

这意味着从根开始向右,向左