拓扑排序(学习)

来源:互联网 发布:淘宝总部地址 编辑:程序博客网 时间:2024/05/17 18:19

拓扑排序:

拓扑排序是对有向无环图的一种排序。
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 < u,v > ∈ E(G),则u在线性序列中出现在v之前。
通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。

由AOV网构造拓扑序列的拓扑排序算法主要是循环执行以下两步,直到不存在入度为0的顶点为止。
(1) 选择一个入度为0的顶点并输出之;

(2) 从网中删除此顶点及所有出边。

循环结束后,若输出的顶点数小于网中的顶点数,则输出“有回路”信息,否则输出的顶点序列就是一种拓扑序列。


实现

邻接矩阵:v*v

    bool G[N][N];           //邻接矩阵存图    int in[N];              //各个顶点的入度 计数    void toposort(int n)    //拓扑排序    {        int k=0;        for(int i=1; i<=n; i++)     //共进行|G.V|次操作        {            for(int j=1; j<=n; j++) //遍历所有的顶点 找入度为0的            {                if(in[j]==0)        //找到                {                    printf("%d%c",j,i==n?'\n':' ');                    in[j]--;        //去掉这个点  让in[j] = -1;                    k=j;            //记录这个点                    break;          //跳出循环                }            }            for(int j=1; j<=n; j++) //遍历所有的点                if(G[k][j]==1)      //找被此点打败过的点                {                    G[k][j]=0;      //标记为找到过                    in[j]--;        //让这个点的入度-1                }        }    }

前向星:v+e

    struct node     //前向星的结构体    {        int v;      //输队编号        int next;    }edge[N*4];     //结构体数组    int head[N];    //头指针数组    int cnt;        //下标    int in[N];      //入度数组    void toposort(int n)    {        priority_queue<int,vector<int>,greater<int> >que;   //优先队列        for(int i=1; i<=n; i++)     //找所有点        if(in[i]==0)                //入度为 0        {            que.push(i);            //加入队列            in[i]--;                //入度 变为 -1        }        int k=1;        while(!que.empty())         //队列不为空        {            int u=que.top();        //取出队首的数            que.pop();              //删除            printf("%d%c",u,k++==n?'\n':' ');            for(int i=head[u]; i!=-1; i=edge[i].next)   //与该点相连的            {                node e=edge[i];     //便于书写                in[e.v]--;          //点的入度 -1                if(in[e.v]==0)      //若此点的 入度为 0                    que.push(e.v);  //放入队列            }        }    }

STL: v+e

    vector<int>G[N];    //vector模拟邻接表    int n,in[N];        //in[]保存每个顶点的入度    void toposort()    {        priority_queue <int,vector <int>,greater<int> > Q;  //优先队列队列元素从小到大        for(int i=1; i<=n; i++)        if(in[i] == 0)  //入度为0的都压入队列            Q.push(i);        int flag=0;        while(!Q.empty())   //BFS思想        {            int v=Q.top();  //取队顶的那个点遍历            Q.pop();        //删掉该点            if(!flag)                cout<<v;            else                cout<<" "<<v;            flag=1;            for(int i=0; i<G[v].size(); i++)                //遍历与该点相邻的点            {                in[G[v][i]]--;                              //与它相连的点的入度都要减1                if(!in[G[v][i]])                            //入度为0压入队列                Q.push(G[v][i]);            }        }        puts("");    }}

以上代码不是自己敲的

0 0
原创粉丝点击