I am trying to construct an euler path for a rooted tree where root can have multiple children (i.e. its not a binary tree). To keep track of each already traversed child I am maintaining a queue in a map. When I encounter a root I simply pop one of its children and set it as root. The problem is whenever, I pop a child and its parent is traversed again the popped node appears again. I am guessing I need to store references of queue but can't get my head around it. Any help would be appreciated.
vector<int> getEulerPath(Node* root) {
Node* node = root;
vector<int> path;
unordered_map<int, queue<Node*>> uvc;
while(node != NULL) {
path.push_back(node->data);
cout << "processing node " << node->data << endl;
if(uvc.find(node->data) != uvc.end()) {
cout << "found queue: " << node->data << endl;
uv = uvc.find(node->data)->second;
} else {
for(int i = 0; i < node->children.size(); i++) {
uv.push(node->children[i]);
}
cout << "adding queue: " << node->data << endl;
uvc.insert(pair<int, queue<Node*>>{node->data, uv});
}
if(!uv.empty()) {
cout << "queue size before popping: " << uv.size() << endl;
cout << "have some children left for : " << node->data << endl;
node = uv.front();
uv.pop();
cout << "queue size after popping: " << uv.size() << endl;
} else {
cout << "no children left reverting back to : " << node->parent->data << endl;
node = node->parent;
}
cout << "new node is: " << node->data << endl;
}
return path;
}
Update
Following is the minimal runnable example
#include <iostream>
#include <vector>
#include <unordered_map>
#include <queue>
using namespace std;
class Node {
public:
vector<Node*> children;
Node* parent;
int data;
Node();
Node(int, Node*);
};
Node::Node() {
parent = NULL;
data = -1;
}
Node::Node(int d, Node* p) {
parent = p;
data = d;
}
Node* generateTree(vector<vector<int>> edges) {
unordered_map<int, Node*> nodes;
Node* root = new Node();
for(int i = 0; i < edges.size(); i++) {
vector<int> edge = edges[i];
Node* parent;
Node* child;
if(nodes.find(edge[0]) == nodes.end()) {
parent = new Node(edge[0], NULL);
nodes.insert(pair<int, Node*>{edge[0], parent});
} else {
parent = nodes.find(edge[0])->second;
}
if(nodes.find(edge[1]) == nodes.end()) {
child = new Node(edge[1], parent);
nodes.insert(pair<int, Node*>{edge[0], child});
} else {
child = nodes.find(edge[1])->second;
}
if(i == 0) root = parent;
parent->children.push_back(child);
}
return root;
}
vector<int> getEulerPath(Node* root) {
Node* node = root;
vector<int> path;
unordered_map<int, queue<Node*>> uvc;
while(node != NULL) {
path.push_back(node->data);
cout << "processing node " << node->data << endl;
queue<Node*> uv;
if(uvc.find(node->data) != uvc.end()) {
cout << "found queue: " << node->data << endl;
uv = uvc.find(node->data)->second;
} else {
for(int i = 0; i < node->children.size(); i++) {
uv.push(node->children[i]);
}
cout << "adding queue: " << node->data << endl;
uvc.insert(pair<int, queue<Node*>>{node->data, uv});
}
if(!uv.empty()) {
cout << "queue size before popping: " << uv.size() << endl;
cout << "have some children left for : " << node->data << endl;
node = uv.front();
uv.pop();
cout << "queue size after popping: " << uv.size() << endl;
} else {
cout << "no children left reverting back to : " << node->parent->data << endl;
node = node->parent;
}
cout << "new node is: " << node->data << endl;
}
return path;
}
int main() {
vector<vector<int>> edges;
edges.push_back(vector<int> {1, 2});
edges.push_back(vector<int> {1, 3});
edges.push_back(vector<int> {1, 4});
edges.push_back(vector<int> {3, 5});
edges.push_back(vector<int> {3, 6});
edges.push_back(vector<int> {3, 7});
Node* root = generateTree(edges);
vector<int> euler_path = getEulerPath(root);
for(int i = 0; i < euler_path.size(); i++) {
cout << euler_path[i] << " ";
}
cout << endl;
return 0;
}
Aucun commentaire:
Enregistrer un commentaire