其他分享
首页 > 其他分享> > c – 使用DFS进行拓扑排序而不进行递归

c – 使用DFS进行拓扑排序而不进行递归

作者:互联网

我知道进行拓扑排序的常用方法是使用DFS进行递归.但是如何使用stack< int>来完成它呢?而不是递归?我需要获得逆转后的订单,但我有点卡住了:

该图是矢量< vector< int>. &GT邻接名单

以下是我想用于拓扑排序的DFS

bool visited[MAX]={0};
stack<int> dfs, postOrder;
vector<int> newVec;
vector<int>::iterator it;

for(int i=0;i<MAX;i++){
    if(visited[i]==false){
        dfs.push(i);
    }   
    while(!dfs.empty()){
        int node=dfs.top();
        dfs.pop();
        visited[node]=true;
        newVec=graph[node]; //vector of neighboors
        for(it=newVec.begin();it!=newVec.end();it++){
            int son=*it;
            if(visited[son]==false){
                dfs.push(son);
            }
        }
    }
}

解决方法:

为了构造postOrder列表,您需要知道算法完成处理节点k的最后一个子节点的时间.

确定何时将最后一个子项弹出堆栈的一种方法是在堆栈上放置特殊标记,以指示特定节点的子节点正在启动的位置.您可以将dfs堆栈的类型更改为vector< pair< bool,int>取代.当bool设置为true时,它表示父项; false表示孩子.

当你从堆栈中弹出一个“子对”(即一对中第一个成员设置为false)时,你运行你当前拥有的代码,即用你的for循环将所有孩子都推到堆栈上.但是,在进入for循环之前,应该将make_pair(true,node)推入堆栈以标记此节点的所有子节点的开头.

当您从堆栈中弹出“父对”时,将父索引推送到postOrder,然后继续:

vector<bool> visited(MAX);
stack<pair<bool,int> > dfs;
stack<int> postOrder;
vector<int> newVec;
vector<int>::iterator it;
vector<vector<int> > graph;
for(int i=0;i<MAX;i++){
    if(visited[i]==false){
        dfs.push(make_pair(false,i));
    }   
    while(!dfs.empty()){
        pair<bool,int> node=dfs.top();
        dfs.pop();
        if (node.first) {
            postOrder.push(node.second);
            continue;
        }
        visited[node.second]=true;
        dfs.push(make_pair(true, node.second));
        newVec=graph[node.second]; //vector of neighboors
        for(it=newVec.begin();it!=newVec.end();it++){
            int son=*it;
            if(visited[son]==false){
                dfs.push(make_pair(false, son));
            }
        }
    }
}

Demo on ideone.

标签:depth-first-search,c,algorithm,stack,topological-sort
来源: https://codeday.me/bug/20191004/1852122.html