我已经看过一些关于如何连接二叉树节点的文章/页面,这些节点处于同一级别,但这些文章都没有明确解释过程/算法。如果有人可以接受,我将不胜感激。代码不是必需的,但用pseudo解释它会很好。
为了便于讨论,我们将树视为:
0
1 2
3 4 5 6
7 9
在上述情况中:
0 should point to null.
1 should point to 2.
3 should point to 4.
....
7 should point to 9.
9 should point to NULL.
基本树结构是:
class Tree {
public:
int data;
Tree* left;
Tree* right;
Tree* next;
}
答案 0 :(得分:1)
这是一种有趣的方法,它不会使用额外的内存,这有点诱导:
第一级已连接(只有一个节点)
我们说级别i
已连接。然后连接级别i+1
执行以下操作:
a)将节点lst
(我们稍后将使用的中间变量)初始化为null
b)从级别i
上的第一个节点开始。
c)从第一个节点开始遍历级别i
上的节点。请注意,您可以轻松遍历级别i
上的节点,因为它已经连接,因此您在每个节点中都有兄弟指针。
d)对于级别i
上的每个节点,首先查看其左侧子节点,然后查看其右侧子节点。对于非空的每个孩子,如果lst
不是null
,请将lst
与该孩子联系起来。然后将lst
设置为该孩子。
连接级别i + 1
后,您可以进入下一级别。如果在遍历级别lst
之后仍为空,则表示此级别上没有节点具有子级=>这是最后一级,你可以停止算法。
很容易说明为什么这样做,它需要线性时间和恒定空间,因此它比带有队列的BFS(带线性内存)严格要好。
答案 1 :(得分:1)
根据Ishamael的想法,我建议采用一种程序
void link_levels(Tree* t){
Tree *head, *tail, *end_of_row;
assert (t != 0);
t->next = 0;
head = tail = end_of_row = t;
while(head != 0){
if(head->left != 0){
tail->next = head->left;
tail = tail->next;
tail->next = 0;
}
if(head->right != 0){
tail->next = head->right;
tail = tail->next;
tail->next = 0;
}
if(head == end_of_row){
head = head->next;
end_of_row->next = 0;
end_of_row = tail;
}
else {
head = head->next;
}
}
}
答案 2 :(得分:0)
根据评论中的建议使用BFS。 然后,您将获得每个节点与根的距离。
伪代码:
vis[1..n] = false // mark each node as un-visited
dis[1..n] = 0
Queue q
dis[root] = 0
vis[root] = true
q.push(root)
while !q.empty()
node x = q.front()
children[] = children nodes of node x
for each child in children
!vis[child]
dis[child] = dis[x] + 1
vis[child] =true
q.enqueue(child)
q.pop()
现在,您将使每个节点与根保持距离,根据距离聚合每个节点,并根据您的要求加入节点。