问题:我需要能够递归通过索引从未知高度的完美二叉树中检索节点。
由于未知的高度属性,似乎唯一有意义的索引形式是广度优先索引(根据标题):
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);
模式很明确 - 但是如何编程 - 不消耗太多时钟周期(这是嵌入式设备) - 从Index
中选择一个节点并将Index
转换为Navigate的参数那个节点?我错过了一个简单的转变吗?
这是我最终使用的实现,建立在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#,尽管实际上每次对Navigate的调用都是在不同的嵌入式设备上处理的,因此需要递归而不是简单地遵循伪代码,构建List
等等。感谢yurib:)。< / p>
答案 0 :(得分:4)
找到第n个节点遵循通过将n
重复除以2并跟踪余数而创建的路径。当1表示正确,0表示左表示时,按照反向余数创建的“路径”。
例如,添加第6项(索引= 5):
6/2 = 3(0)
3/2 = 1(1)
这意味着从右边开始,向左移动。