我正在开发一个程序,其中逐级打印树。我的问题是我尝试使用与此相似的格式。
我目前的格式在哪里
到目前为止,我的代码是
void BTree::levelOrder(Node root) {
queue<Node> queue;
queue.push(root);
while(!queue.empty()) {
Node tempNode=queue.front();
queue.pop();
cout<<tempNode.value<<" ";
if(tempNode.left!=NULL)
queue.push(*tempNode.left);
if(tempNode.right!=NULL)
queue.push(*tempNode.right);
}
}
答案 0 :(得分:0)
不幸的是,OP没有公开MCVE。
因此,我从struct Node
开始重现OP的问题:
struct Node {
int value;
Node *left, *right;
Node(int value, Node *left, Node *right):
value(value), left(left), right(right)
{ }
explicit Node(int value):
Node(value, nullptr, nullptr)
{ }
~Node() = default;
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
};
...和一个用于打印节点的功能(用于测试):
void printInOrder(const Node &node, int indent = 0)
{
if (node.left) printInOrder(*node.left, indent + 2);
std::cout << std::setw(indent) << ""
<< "node" << node.value << '\n';
if (node.right) printInOrder(*node.right, indent + 2);
}
用于再现OP数据的示例程序:
int main()
{
// build tree
Node node11(11);
Node node10(10, nullptr, &node11);
Node node7(7);
Node node9(9, &node7, &node10);
Node node3(3);
Node node5(5, &node3, &node9);
// dump tree to console
std::cout << "Print tree inorder:\n";
printInOrder(node5);
// done
return 0;
}
输出:
Print tree inorder:
node3
node5
node7
node9
node10
node11
转储的树看起来像OP所描述的。
现在,我类似于OP的功能:
void printLevelOrder(const Node &root)
{
std::queue<const Node*> queue;
queue.push(&root);
while (!queue.empty()) {
const Node *node = queue.front();
queue.pop();
std::cout << "node" << node->value << " ";
if (node->left) queue.push(node->left);
if (node->right) queue.push(node->right);
}
}
输出:
Print tree in levels:
node5 node3 node9 node7 node10 node11
我不确定为什么OP指出输出将包含4行–没有任何东西可以在OP代码的任何一行中打印换行符。可能是,OP不敢公开他的失败尝试。但是,问题是不一致的。
我的printInOrder()
函数中已经显示了一种可能的/通常的解决方案:节点的遍历必须对深度进行额外的记账。实际上,这非常容易,因为每个节点都可以通过简单的增量将其深度应用于子节点。
虽然printInOrder()
是一种递归算法(深度可以作为额外的参数传递),但OPs函数是一种迭代算法。因此,恕我直言,最简单的解决方案是将深度簿记添加到队列条目:
void printLevelOrder(const Node &root)
{
typedef std::pair<const Node*, int> NodeLevel;
std::queue<NodeLevel> queue;
queue.push(std::make_pair(&root, 0));
while (!queue.empty()) {
const NodeLevel nodeLevel = queue.front();
queue.pop();
std::cout << nodeLevel.second << ": node" << nodeLevel.first->value << " ";
if (nodeLevel.first->left) {
queue.emplace(nodeLevel.first->left, nodeLevel.second + 1);
}
if (nodeLevel.first->right) {
queue.emplace(nodeLevel.first->right, nodeLevel.second + 1);
}
}
}
输出:
Print tree in levels:
0: node5 1: node3 1: node9 2: node7 2: node10 3: node11
现在,仅缺少最后一步-将深度信息转换为足够的格式输出。因此,必须考虑到节点本身的深度不是那么重要。相反,当深度发生变化时(与前一个相比),它更相关:
void printLevelOrder(const Node &root)
{
typedef std::pair<const Node*, int> NodeLevel;
std::queue<NodeLevel> queue;
queue.push(std::make_pair(&root, 0));
for (int level = 0; !queue.empty();) {
const NodeLevel nodeLevel = queue.front();
queue.pop();
if (level != nodeLevel.second) std::cout << '\n';
std::cout << nodeLevel.second << ": node" << nodeLevel.first->value << " ";
if (nodeLevel.first->left) {
queue.emplace(nodeLevel.first->left, nodeLevel.second + 1);
}
if (nodeLevel.first->right) {
queue.emplace(nodeLevel.first->right, nodeLevel.second + 1);
}
level = nodeLevel.second;
}
}
输出:
Print tree in levels:
0: node5
1: node3 1: node9
2: node7 2: node10
3: node11
仍然缺少适当的缩进。
经过与n.m.的讨论,我尝试了一下,并再次修改了示例以实现正确的格式。因此,我也考虑了不存在的节点(将nullptr
推入占位符)。因此,终止循环还需要另一个条件–仅包含nullptr
的级别由标志nextLevelEmpty
标记:
void printLevelOrder(const Node &root)
{
typedef std::pair<const Node*, int> NodeLevel;
std::queue<NodeLevel> queue;
queue.push(std::make_pair(&root, 0));
bool nextLevelEmpty = false;
for (int level = -1;;) {
const NodeLevel nodeLevel = queue.front();
queue.pop();
if (level != nodeLevel.second) { // new level
std::cout << '\n';
if (nextLevelEmpty) return;
nextLevelEmpty = true;
}
std::cout << std::setw(3);
if (nodeLevel.first) std::cout << nodeLevel.first->value;
else std::cout << 'x';
if (nodeLevel.first) {
queue.emplace(nodeLevel.first->left, nodeLevel.second + 1);
queue.emplace(nodeLevel.first->right, nodeLevel.second + 1);
nextLevelEmpty &= !nodeLevel.first->left && !nodeLevel.first->right;
} else {
queue.emplace(nullptr, nodeLevel.second + 1);
queue.emplace(nullptr, nodeLevel.second + 1);
}
level = nodeLevel.second;
}
}
输出:
Print tree in levels:
5
3 9
x x 7 10
x x x x x x x 11
我必须承认,现在,输出看起来像OP的预期。 好像是下午感觉更好/合适。