简洁明了的拓扑图算法讲解

拓扑图:

算法思想:类似于二叉树的层次遍历,遍历所有结点,将入度为0的结点存在一个栈中,依次输出栈内的各个结点时,将每个节点的子节点的度减1,然后将其中度为0的结点存入栈中,循环执行上述操作,直到所有结点遍历完。

举个例子,如下图所示

简洁明了的拓扑图算法讲解_第1张图片

第一步,(A,B,C,D,E)的度数分别为(0,2,1,3,0)先将入度为0的结点存入栈中,(A,E)入栈,A出栈,则相应的结点D的度数3减变为2,结点B的度数2减1变为1,继续将栈中的E出栈,此时B的度数为1-1=0,则将度为0的结点B进栈,此时B出栈,相应C的读书为1-1=0;结点C进栈,相应D的度数为2-1=1,不做任何操作,然后结点C出栈,相应结点D的的度数为1-1=0,结点D入栈,找不到别的可以遍历的结点,算法执行结束,如下输出序列为

简洁明了的拓扑图算法讲解_第2张图片

相应代码如下

//增加度数后的邻接矩阵
typedef struct Anode{
    char a;
    int count;
    node *first;
}Anode;
int justice(ag b)
{
    //先从度为0的结点开始依序进行层次遍历,利用数组和前后指针来完成该操作
    int i,fre=0,end=1,stack[max];
    node* p; 
    //先遍历第一个度为0结点相关操作
    for(i=0;iif(a.First[i].count==0)
        stack[++fre];
    }
    //接下来进行循环层次遍历
    while(end>fre)
    {
        i=stack[end];printf("%d",i);
        p=a.First[i]->first;
        while(p!=null)
        {
            j=p->vax;//指向结点的标号
            a.First[j].count--;
            if(a.First[j].count==0)
            {
                stack[++fre]=j;
            }
            p=p->next;
        }
        ++end;
    }
    //如果栈最后存储的数等于总的结点数,输出1,反之,输出0
    if(fre==a.n)
        return 1;
    return 0;
}

你可能感兴趣的:(简洁明了的拓扑图算法讲解)