拓扑排序

 

首先构造邻接表:

#define MaxVertexNum 100000

typedef int Vertex;

typedef int Weight;
//表节点 
typedef struct ArcNode
{
    Vertex to;
    Weight w;
    struct ArcNode *next;
}ArcNode;
//顶点 
typedef struct ANode
{
    Vertex id;
    ArcNode *first;
    int into;
}ANode;
//
typedef struct LGraph
{
    int v, e;
    ANode* g[MaxVertexNum];
}LGraph; 

 

(1)找出图中入度为0的节点,将其加入到拓扑序列中,并且将以它为尾的弧都删除。

(2)循环(1),直到所有点都加入到拓扑序列中或者已经没有入读为0的节点。

 

算法如下:

bool TopSort(LGraph& G)
{
    Vertex top[G.v];
    memset(top, -1, sizeof(top));
    
    bool flag[G.v] = {false};
    
    for(Vertex i = 0; i < G.v; i++)
    {
        for(Vertex j = 0; j < G.v; j++)
        {
            if(G.g[j].into == 0 && flag[j] == false)
            {
                top[i] = j;
                flag[j] = true;
                break;
            }
        }
        if(j == G.v)
        {
            Error('拓扑序列不存在');
            return false;
        }
        for(ArcNode* a = G.g[j].first; a != NULL; a = a->next)
        {
            G.g[a->to].into--;
        }
        
    }
        return true;
} 

 

上面的算法在每次查找入度为0的节点上面浪费了很多的时间,很不划算,下面这个算法进行一个优化。
bool topSort(LGraph& G)
{
    //自定义队列
    Queue q;
    //先将一开始入度为0的节点加入队列 
    for(int i = 0; i < G.v; i++)
    {
        if(G.g[i].into == 0)
            q.push(i);    
    }
    
    int count = 0;
    Vertex top[G.v] = {-1};
    
    while(!q.empty())
    {
        Vertex t = q.pop();
        top[count++] = t;
        ArcNode* a = G.g[t].first;
        //删除以t为尾的弧 
        while(a)
        {
            G.g[a->to].into--;
            if(G.g[a->to].into == 0)
                q.push(a->to); 
            a = a->next;
        }
    }
    if(count != G.v)
    {
        Error('不能得到拓扑序列');
        return false;
    }
    return true;
}

 



posted @ 2019-04-23 11:01  yangzixiongh  阅读(109)  评论(0编辑  收藏  举报