在接受采访时我问过这个问题:
假设我们有上面的二叉树,我怎么能产生如下的输出
2 7 5 2 6 9 5 11 4
我回答说,我们可以拥有一个级别计数变量,并通过检查每个节点的级别计数变量来顺序打印所有元素。 可能我错了。
任何人都可以说明我们如何实现这一目标吗?
答案 0 :(得分:6)
您需要对树进行广度优先遍历。 Here描述如下:
广度优先遍历:深度优先 不是唯一可以通过的方式 一棵树的元素。另一种方式是 逐级完成它们。
例如,每个元素都存在于a 树中的某个级别(或深度):
tree
----
j <-- level 0
/ \
f k <-- level 1
/ \ \
a h z <-- level 2
\
d <-- level 3
人们喜欢开始编号 用0。)
所以,如果我们想访问这些元素 逐级(和从左到右,如 通常),我们将从0级开始 j,然后转到f和k的1级, 然后转到第2级a,h和z,和 最后到第3级进行d。
这种逐级遍历是 称为广度优先遍历 因为我们探索广度,即 给定的树的全宽 等级,然后再深入。
答案 1 :(得分:2)
您问题中的遍历称为level-order traversal
,而this就是如何完成的(我发现非常简单/干净的代码段)。
您基本上使用队列,操作顺序如下:
enqueue F
dequeue F
enqueue B G
dequeue B
enqueue A D
dequeue G
enqueue I
dequeue A
dequeue D
enqueue C E
dequeue I
enqueue H
dequeue C
dequeue E
dequeue H
对于这棵树(直接来自维基百科):
答案 2 :(得分:2)
这个术语是级别顺序遍历。维基百科描述了an algorithm for that using a queue:
levelorder(root)
q = empty queue
q.enqueue(root)
while not q.empty do
node := q.dequeue()
visit(node)
if node.left ≠ null
q.enqueue(node.left)
if node.right ≠ null
q.enqueue(node.right)
答案 3 :(得分:2)
BFS:
std::queue<Node const *> q;
q.push(&root);
while (!q.empty()) {
Node const *n = q.front();
q.pop();
std::cout << n->data << std::endl;
if (n->left)
q.push(n->left);
if (n->right)
q.push(n->right);
}
迭代加深也会起作用并节省内存使用,但代价是计算时间。
答案 4 :(得分:2)
如果我们能够在同一级别获取下一个元素,我们就完成了。根据{{3}},我们可以使用广度优先遍历来访问这些元素。
现在唯一的问题是如何检查我们是否处于任何级别的最后一个元素。因此,我们应该附加一个分隔符(在本例中为NULL)来标记一个级别的结尾。
算法:
1.将root置于队列中。
2.将NULL放入队列中
3.队列不空时
4. x =从队列中获取第一个元素
5.如果x不为NULL
6. x-&gt; rpeer&lt; =队列的顶部元素
7.将x的左右孩子放在队列中
8.别的
9.如果队列不为空
10.将NULL放入队列中
11.结束如果
12.结束时
13.返回
#include <queue>
void print(tree* root)
{
queue<tree*> que;
if (!root)
return;
tree *tmp, *l, *r;
que.push(root);
que.push(NULL);
while( !que.empty() )
{
tmp = que.front();
que.pop();
if(tmp != NULL)
{
cout << tmp=>val; //print value
l = tmp->left;
r = tmp->right;
if(l) que.push(l);
if(r) que.push(r);
}
else
{
if (!que.empty())
que.push(NULL);
}
}
return;
}
答案 5 :(得分:0)
我会使用一个集合,例如std::list
,用于存储当前打印级别的所有元素:
答案 6 :(得分:0)
作为你在面试时可以做什么的一个例子,如果你不记得/不知道“官方”算法,我的第一个想法是 - 在常规预订中遍历树,拖动一个水平计数器,维护每个级别节点的链接列表向量,例如
levels[level].push_back(&node);
最后打印每个级别的列表。