"Climbing"二叉树
"Climbing" a binary tree
是否有某种方法可以直接爬到树而不访问其他分支?例如,如果我有数字11,我必须访问它,先到2,然后到5,然后到11,而不需要任何搜索。
0
/
/
/
1 2
/ /
/ /
3 4 5 6
/ / / /
/ / / /
7 8 9 10 11 12 13 14
我浪费了很多时间我现在唯一得到的就是要得到N的第一条路径(1或2)你必须(N -1)/2,直到N等于1或2。例子:(12 - 1)/2 =>(5 - 1)/2 => 2。(7-1)/2=>(3-1)/2 => 1。(11-1)/5=>(2-1)/2 => 1。但是最后,将根(0)剪掉并将2当作一个新根来处理是正确的:
2
/
/
/
5 6
/ /
/ /
11 12 13 14
to
0
/
/
/
1 2
/ /
/ /
3 4 5 6
解决方案:
int climb(int ID, Tree<int> t)
{
int time = 0;
if (tree.exists()) {
time += t.value();
tree t1, t2;
t.branches(t1, t2);
int branch = ID;
while (branch > 2) branch = (branch - 1)/2;
int offset = 1;
while (offset*2 < ID - 1) offset *= 2;
if (aux == 1) time += climb(ID - offset2/, a1);
if (aux == 2) time += climb(ID - offset, a2);
}
return time;
}
可以访问全二叉树的任意(1、5、13等)元素
如果您想跳过所有节点之间使用哈希容器(例如std::map
或std::set
)和哈希搜索。二叉树是用来递归遍历的。请注意,set
不是关联的,所以你必须围绕它工作一点。
如果你太努力地在树/树节点中添加自定义代码/成员变量,你可能会得到一个占用大量内存的树式隐含(David的回答就是一个很好的例子)。
—edit—
如果你的id总是一个没有太多漏洞的序列(例如0, 1, 2,..., 50
或68, 69,...,230,231
),我建议使用普通的旧数组!如果你想知道更多,请告诉我。
一般来说,我的建议是首先选择正确的容器/结构,然后只有在需要时才对结构本身进行"轻微"修改。
我假设您有一个完美的二叉树(所有的叶子都在相同的深度,并且每个父节点都有两个子节点),并且所有节点的值都与您提供的示例相似。
在本例中,注意以下内容:
- 节点n的子节点值为2*n+ 1,2 *n+2
- 如果你想去一个奇数K的节点,那么它的父节点是(K-1)/2
- 如果要访问K值为偶数的节点,则其父节点为(K-2)/2
你重复同样的过程,因为你到达节点0,你有所有你要访问的节点。
对于你的例子,你想访问节点11。
11 is odd so its parent is (11-1)/2 = 5
5 is odd so its parent is (5-1)/2 = 2
2 is even so its parent is (2-2)/0 = 0
we have reached the root node, so you have to follow the path 0->2->5->11
我想"爬"到任何分支或叶子,而不访问不妨碍的分支(如果我爬到'4',那么我直接从0 -> 2 -> 4)。我错过的唯一路径是偏移,将"变形"分支到树(见问题)。
我得到了这样的偏移:
int offset = 1;
while (offset*2 < ID - 1) offset *= 2;
它适用于分支'2',offset/2将适用于分支'1'。
int climb(int ID, Tree<int> t)
{
int time = 0;
if (tree.exists()) {
time += t.value();
tree t1, t2;
t.branches(t1, t2);
int branch = ID;
while (branch > 2) branch = (branch - 1)/2;
int offset = 1;
while (offset*2 < ID - 1) offset *= 2;
if (aux == 1) time += climb(ID - offset2/, a1);
if (aux == 2) time += climb(ID - offset, a2);
}
return time;
}
另一种方法是创建堆栈:
void solve(int n)
{
stack<direction> path;
//Calculate the way
while (n > 0)
{
if (n & 1) // if n is odd;
path.push_back(left);
else
path.push_back(right);
n = (n - 1) / 2;
}
//Do actual "climbing"
while (!path.empty())
{
if (path.top() == left)
{
go left
}
else
{
go right
}
path.pop();
}
}
感谢Raving_Zealot from linux.org.ru
- 从父数组测试用例构造二叉树失败
- 打印时有二叉树问题.用户输入不打印任何内容
- 试图找到二叉树的深度
- 二叉树结构平衡,使用递归时EXC_BAD_ACCESS
- 指向二叉树中新节点的指针
- 我试图用这段代码找到二叉树的高度,但它一直返回 0,有人可以告诉我为什么吗?
- C++:如何计算二叉树中其值模块高度小于 2 的节点数?
- 二叉树级别顺序遍历在leetcode中
- 运行无限循环的最小二叉树问题
- 打印二叉树中的常见元素
- 二叉树基准测试结果
- 带有矢量重复值的二叉树打印出来
- 签入二叉树的函数是平衡C++
- 我有两棵二叉树.我想在不更改输入树的情况下深度复制两个二叉树的结果
- 如何计算给定数字在二叉树中出现的次数?
- 为什么我的二叉树会覆盖其根的叶子?
- 将二叉树的节点插入链表 (C++)
- 二叉树级别顺序插入 c++
- 在 C++ 中创建两个不同的二叉树时出现分段错误
- "Climbing"二叉树