Jon*_*Jon 5 c++ recursion graph depth-first-search topological-sort
我最初有一个用于拓扑排序的递归解决方案:
void dfs(int v, bool visited[], node* adjList[], std::stack<int> &myStack) {
visited[v] = true;
node* curr = adjList[v];
while (curr != NULL) {
if(!visited[curr->val]) {
dfs(curr->val, visited, adjList, myStack);
}
curr = curr->next;
}
myStack.push(v);
}
Run Code Online (Sandbox Code Playgroud)
它似乎对我的目的有用。但我无法将其转化为迭代解决方案。这是我的尝试:
void dfs(int v, bool visited[], node* adjList[], std::stack<int> &myStack) {
std::stack<int> recursion;
visited[v] = true;
recursion.push(v);
while( !recursion.empty() ) {
v = recursion.top();
recursion.pop();
node* curr = adjList[v];
myStack.push(v);
while (curr != NULL) {
if(!visited[curr->val]) {
visited[curr->val] = true;
recursion.push(curr->val);
}
curr = curr->next;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但顺序完全乱了!我认为这可能是由于我的定位myStack.push(v),但我不知道如何解决这个问题。任何帮助将不胜感激。
我想我解决了我自己的问题。本质上,您可以通过按节点完成时间对节点进行排序来获得拓扑顺序。但我们可以将其保持为 O(n),而不是进行排序并获得 O(nlogn) 解决方案。当您完成节点时,我们可以将节点的唯一标识符弹出到堆栈中,而不是记录其完成时间。由于在我的例子中我们只处理正顶点,因此将唯一标识符设置为顶点值的负值就足够了。因此,如果我们连续弹出堆栈,我们将得到拓扑顺序。
void dfs(int v, bool visited[], node* adjList[], std::stack<int> &myStack) {
std::stack<int> recursion;
visited[v] = true;
recursion.push(v);
while( !recursion.empty() ) {
v = recursion.top();
recursion.pop();
//A dummy node to denote finish order (e.g. topological order)
if (v < 0) {
myStack.push(v * -1);
} else {
node* curr = adjList[v];
recursion.push(v * -1);
while (curr != NULL) {
if(!visited[curr->val]) {
visited[curr->val] = true;
recursion.push(curr->val);
}
curr = curr->next;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)