关闭

拓扑排序(学习)

200人阅读 评论(0) 收藏 举报

拓扑排序:

拓扑排序是对有向无环图的一种排序。
对一个有向无环图(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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:33961次
    • 积分:3212
    • 等级:
    • 排名:第11021名
    • 原创:302篇
    • 转载:8篇
    • 译文:0篇
    • 评论:6条