0

I am writing a piece of C++ code to perform a Breadth First traversal of a directed graph.

In the main function I define a total of 7 nodes and establish the connections among them. One Node is a struct which contains a name, a value and a list of all children nodes.

I call function breadthFirstTraversal(const Node& root), which uses a queue to go through all the nodes and prints them as they're dequeued.

My main issue is that the lists of deeper nodes appear to be empty, even though children nodes were added to them.

A node:

struct Node_ {
    std::string nodeName = "";
    uint32_t taskCost = 0x0;
    uint64_t maxCost = 0x0;
    std::list<Node_> children;
    bool visited = false;
};
typedef struct Node_ Node;

Nodes:

main(){

    /* Node declaration here... */

    node1.children.push_back(node2);
    node1.children.push_back(node3);
    node2.children.push_back(node4);
    node3.children.push_back(node4);
    node4.children.push_back(node5);
    node4.children.push_back(node6);
    node5.children.push_back(node7);
    node6.children.push_back(node7);

    printNode(node1);
    printNode(node2);
    printNode(node3);
    printNode(node4);
    printNode(node5);
    printNode(node6);
    printNode(node7);

    breadthFirstTraversal(node1);

}

Traversal function:

void breadthFirstTraversal(const Node& root) {

std::cout << "\n\n\nBreadth first traversal!\n";

std::list<Node> q;

// Insert first elem
q.push_back(root);

while (!q.empty()) {

    std::cout << "new iteration\n";

    Node auxNode = q.front();
    std::cout << "pop " << auxNode.nodeName << "\n";
    printNode(auxNode);
    auxNode.visited = true;

    for (Node child : auxNode.children) {
        if (!child.visited) {
            std::cout << "push child " << child.nodeName << "\n";
            q.push_back(child);
        }
    }

    q.pop_front();

}

}

Here is the output. As you can observe, node2 and node3 have no children, even though nodes were added to those lists.

Breadth first traversal!
new iteration
pop root
Node: {name= root, taskCost=0, maxCost=0, visited=0, children=[node2,node3,]}
push child node2
push child node3
new iteration
pop node2
Node: {name= node2, taskCost=6, maxCost=0, visited=0, children=[]}
new iteration
pop node3
Node: {name= node3, taskCost=9, maxCost=0, visited=0, children=[]}
ismarlowe
  • 119
  • 2
  • 13
  • 1
    You're making copies of nodes by pushing them before you fill their children. I.e. the node2 you pushed into node1 is a *copy* of node2. Therefore, updates thereafter to node2 locally are not reflected in that copy. Push the leafs into their parents, they their parents into their parents, until you finally arrive at root. – WhozCraig Oct 28 '19 at 21:41

1 Answers1

-1

De-queueing in c++ is like taking front() and also pop_front! Your pop_front() actually could pop children than the item. Here is update code:

void breadthFirstTraversal(const Node& root) {

std::cout << "\n\n\nBreadth first traversal!\n";

std::list<Node> q;

// Insert first elem
q.push_back(root);

while (!q.empty()) {

    std::cout << "new iteration\n";

    Node auxNode = q.front();
    q.pop_front();
    std::cout << "pop " << auxNode.nodeName << "\n";
    printNode(auxNode);
    auxNode.visited = true;

    for (Node child : auxNode.children) {
        if (!child.visited) {
            std::cout << "push child " << child.nodeName << "\n";
            q.push_back(child);
        }
    }

}

}
SarvanZ
  • 90
  • 4