码迷,mamicode.com
首页 > 编程语言 > 详细

拓扑排序

时间:2015-04-06 14:16:14      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:

可以将图的拓扑排序看作是将图的所有结点在同一水平线上排开,图的所有有向边都从左指向右.

有向无环图的拓扑排序算法:

Toplogical-Sort(G)
    call DFS(G) to compute finish times v.f for each vertex v
    as each vertex is finished,insert onto the front of a linked list
   //因为后被发现的结点的完成时间小于先被发现的结点 //实际上这里是按完成时间将结点从小到大排序 return the linked list of vertices

时间复杂度:O(|V|+|E|)

 

另一种算法:重复寻找入度为0的结点,输出该结点,将该结点及从其出发的边删除.

void find_indegree(Graph G,vector<int> &indegree){
    for(int i=0;i<G.Adj.size();++i){
        indegree.push_back(G.Adj[i].indegree);
    }
}
void toplogical_sort2(Graph G){
    vector<int> indegree;
    find_indegree(G,indegree);
    stack<int> S;
    for(int i=0;i<G.Adj.size();++i){
        if(!indegree[i]){
            S.push(i);//入度为0的结点入栈
        }
    }
    int count = 0;
    while(!S.empty()){
        int i=S.top();//栈顶元素出栈
        S.pop();
        cout<<G.Adj[i].vertex<<",";
        ++count;
        for(auto p=G.Adj[i].firstNode;p != nullptr;p = p->next){
            int k=p->index;
                        //删除从结点i出发的边
            if(!(--indegree[k])){
                S.push(k);
            }
        }
    }
    assert(count == G.Adj.size());//若count<G.Adj.size(),则图中有回路
}

时间复杂度:O(|V|+|E|)

编码实现:

技术分享
#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
#include<stack>
#include<cassert>
using namespace std;
enum Color{white,gray,black};

vector<pair<int,int>> toplogical_list;

class Node{
public:
    int index;
    Node* next=nullptr;//
    Node(int i):index(i){}
};

class VNode{
public:
    char vertex;
    int dist;
    int final;
    int indegree;
    Color color=white;
    int prev=-1;
    Node* firstNode=nullptr;
    VNode(char c):vertex(c){}
};


typedef struct Graph{
    int EdgeNum;
    vector<VNode> Adj;
}Graph;

void DFS_VISIT(Graph &G,int u);
int timex;
void DFS(Graph &G){
    for(int i=0;i<G.Adj.size();i++){
        G.Adj[i].color = white;
        G.Adj[i].prev = -1;
    }
     timex =0;
     //begin from a certain vertex
     //DFS_VISIT(G,inndex);
    for(int i=0;i<G.Adj.size();i++){
        if(G.Adj[i].color == white){
            DFS_VISIT(G,i);
        }
    }
}

void DFS_VISIT(Graph &G,int u){
    timex += 1;
    G.Adj[u].dist = timex;
    G.Adj[u].color = gray;
    //cout<<G.Adj[u].vertex<<",";
    
    Node* pv = G.Adj[u].firstNode;
    while(pv != nullptr){
        int v= pv->index;
        if(G.Adj[v].color == white){
            G.Adj[v].prev = u;
            DFS_VISIT(G,v);
        }
        pv = pv->next;
    }
    G.Adj[u].color = black;
    timex += 1;
    G.Adj[u].final = timex;
    toplogical_list.push_back(make_pair(u,timex));
}

int comp(pair<int,int> a,pair<int,int> b){
    if(a.second>b.second){
        return -1;
    }
    else if(a.second==b.second){
        return 0;
    }
    else{
        return 1;
    }
}
void toplogical_sort(Graph G){
    DFS(G);
    sort(toplogical_list.begin(),toplogical_list.end(),comp);
    for(const auto &c:toplogical_list ){
        cout<<G.Adj[c.first].vertex<<",";
    }
    cout<<endl;
}

void find_indegree(Graph G,vector<int> &indegree){
    for(int i=0;i<G.Adj.size();++i){
        indegree.push_back(G.Adj[i].indegree);
    }
}
void toplogical_sort2(Graph G){
    vector<int> indegree;
    find_indegree(G,indegree);
    stack<int> S;
    for(int i=0;i<G.Adj.size();++i){
        if(!indegree[i]){
            S.push(i);
        }
    }
    int count = 0;
    while(!S.empty()){
        int i=S.top();
        S.pop();
        cout<<G.Adj[i].vertex<<",";
        ++count;
        for(auto p=G.Adj[i].firstNode;p != nullptr;p = p->next){
            int k=p->index;
            if(!(--indegree[k])){
                S.push(k);
            }
        }
    }
    assert(count == G.Adj.size());
}

int main(){
    Graph G;
    G.EdgeNum = 9;
    //vector<char> v{‘v‘,‘r‘,‘s‘,‘w‘,‘x‘,‘y‘,‘t‘,‘u‘};
    vector<char> v{v,r,s,w,x,y,t,u,p};
    for(int i=0;i<v.size();i++){
        G.Adj.push_back(VNode(v[i]));
    }

    int i,j;
    for(int k=0;k<G.EdgeNum;k++){
        cin>>i>>j;
        Node* p = new Node(j);
        p->next = G.Adj[i].firstNode;
        G.Adj[i].firstNode = p;

        ++G.Adj[j].indegree;
        /*
        p = new Node(i);
        p->next = G.Adj[j].firstNode;
        G.Adj[j].firstNode = p;
        */
    }
    //DFS(G);
    toplogical_sort(G);
    toplogical_sort2(G);
    cout<<endl;
    return 0;
}
View Code

 

拓扑排序

标签:

原文地址:http://www.cnblogs.com/bukekangli/p/4395791.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!