u01: Add recursive print with cycle detection

This commit is contained in:
Simon Bruder 2023-04-22 12:53:34 +02:00
parent 08dc634ebb
commit 1f56b00800
4 changed files with 42 additions and 0 deletions

View file

@ -7,6 +7,14 @@ int main(int argc, char **argv) {
std::cout << *t;
delete t;
t = nullptr;
node *n = new node("foo");
n->add_child(new node("bar"));
n->get_child(0)->add_child(n);
std::cout << n->print_recursive();
delete n;
n = nullptr;
node *root = new node("root");
root->add_child(new node("left child"));
root->add_child(new node("right child"));

View file

@ -42,6 +42,24 @@ void node::print(std::ostream &str, std::size_t depth) const {
}
}
std::string node::print_recursive(std::size_t depth,
std::set<const node *> visited) const {
std::stringstream output;
output << std::string(depth, '\t') << get_name();
visited.insert(this);
for (const node *child : children) {
// std::set::contains is only implemented in C++20
if (visited.find(child) == visited.end()) {
output << std::endl << child->print_recursive(depth + 1, visited);
} else {
output << " [↝ " << child->get_name() << "]";
}
}
if (depth == 0)
output << std::endl;
return output.str();
}
std::ostream &operator<<(std::ostream &os, node &n) {
n.print(os);
return os;

View file

@ -1,6 +1,7 @@
#pragma once
#include <memory>
#include <set>
#include <string>
#include <vector>
@ -14,6 +15,8 @@ public:
node *get_child(std::size_t i) const;
void add_child(node *child);
void print(std::ostream &str, std::size_t depth = 0) const;
std::string print_recursive(std::size_t depth = 0,
std::set<const node *> visited = {}) const;
private:
std::string name;

View file

@ -150,3 +150,16 @@ TEST_CASE("Print stream overload") {
REQUIRE(output1.str() == output2.str());
}
TEST_CASE("Cycle detection") {
node *n = new node("foo");
n->add_child(new node("bar"));
n->get_child(0)->add_child(n);
std::stringstream output;
output << n->print_recursive();
REQUIRE(output.str() == "foo\n\tbar [↝ foo]\n");
delete n;
}