AOV网络拓扑排序

这个算法,主要是为输出一个无环图的拓扑序列

算法思想:

主要依赖一个栈,用来存放没有入度的节点,每次读取栈顶元素,并将栈顶元素的后继节点入度减一,如果再次出现入度为零的节点,就加入到栈中。参考《大话数据结构》,写下下面完整代码,并发现,其中程序的进行,出现错误。v6执行完,应该执行v9,因为此时v9是站顶元素,并不是v0.

算法流程:

复制代码
int topGraph(graph g){
    EdgeNode *e;
    int i,k,gettop;
    int top = 0 ;
    int count = 0;
    int *stack;
    stack = (int *)malloc(g->numVertexes * sizeof(int));
    for(i=0;i<g->numVertexes;i++){ 
        if(g->headlist[i].in == 0) //把入度为0的,即没有入度的点入栈
            stack[++top] = i;
    }
    while(top){
        gettop = stack[top--];
        printf("%d ",gettop);
        count++;
        for(e = g->headlist[gettop].fnode; e ; e=e->next){ //一次遍历链表,减少各个子节点的入度
            k = e->data;
            if(!(--g->headlist[k].in))
                stack[++top] = k;
        }
    }
    if(count < g->numVertexes)
        return ERROR;
    else
        return OK;
}
复制代码

全部代码:

复制代码
#include <stdio.h>
#include <stdlib.h>
#define MAX 14
#define ERROR 1
#define OK 0
typedef struct edgeNode{
    int data;
    struct edgeNode *next;
}EdgeNode;
typedef struct headNode{
    int in;
    int data;
    EdgeNode *fnode;
}HeadNode,HeadList[MAX];
typedef struct{
    HeadList headlist;
    int numEdges,numVertexes;
}Graph,*graph;

void initGraph(graph g);
int inputInfo(graph g,int tar,int in,int data,int first);
void printGraph(graph g);
int topGraph(graph g);
int main(){
    Graph *g = (Graph *)malloc(sizeof(Graph));
    initGraph(g);
    printGraph(g);

    if(topGraph(g) == ERROR)
        printf("有环路!\n");
    else
        printf("没有环路!\n");

    free(g);
    getchar();
    return 0;
}
int topGraph(graph g){
    EdgeNode *e;
    int i,k,gettop;
    int top = 0 ;
    int count = 0;
    int *stack;
    stack = (int *)malloc(g->numVertexes * sizeof(int));
    for(i=0;i<g->numVertexes;i++){ 
        if(g->headlist[i].in == 0) //把入度为0的,即没有入度的点入栈
            stack[++top] = i;
    }
    while(top){
        gettop = stack[top--];
        printf("%d ",gettop);
        count++;
        for(e = g->headlist[gettop].fnode; e ; e=e->next){ //一次遍历链表,减少各个子节点的入度
            k = e->data;
            if(!(--g->headlist[k].in))
                stack[++top] = k;
        }
    }
    if(count < g->numVertexes)
        return ERROR;
    else
        return OK;
}
void printGraph(graph g){
    int i;
    printf("vertex:%d,edges:%d\n",g->numVertexes,g->numEdges);
    EdgeNode *e = (EdgeNode *)malloc(sizeof(EdgeNode));
    for(i=0;i<MAX;i++){
        printf("[in:%d]%d",g->headlist[i].in,g->headlist[i].data);    
        e = g->headlist[i].fnode;
        while(e != NULL){    
            printf("->%d",e->data);
            e = e->next;
        }    
        printf("\n");
    }
    free(e);
}
void initGraph(graph g){
    g->numVertexes = MAX;
    g->numEdges = 0;
    int i;
    for(i=0;i<MAX;i++){
        g->headlist[i].fnode = NULL;
    }
    inputInfo(g,0,0,0,4);
    inputInfo(g,0,0,0,5);
    inputInfo(g,0,0,0,11);

    inputInfo(g,1,0,1,2);
    inputInfo(g,1,0,1,4);
    inputInfo(g,1,0,1,8);

    inputInfo(g,2,2,2,5);
    inputInfo(g,2,2,2,6);
    inputInfo(g,2,2,2,9);

    inputInfo(g,3,0,3,2);
    inputInfo(g,3,0,3,13);

    inputInfo(g,4,2,4,7);

    inputInfo(g,5,3,5,8);
    inputInfo(g,5,3,5,12);

    inputInfo(g,6,1,6,5);

    inputInfo(g,7,2,7,-1);

    inputInfo(g,8,2,8,7);

    inputInfo(g,9,1,9,10);
    inputInfo(g,9,1,9,11);

    inputInfo(g,10,1,10,13);

    inputInfo(g,11,2,11,-1);

    inputInfo(g,12,1,12,9);

    inputInfo(g,13,2,13,-1);
}
int inputInfo(graph g,int tar,int in,int data,int first){
    g->numEdges++;
    
    if(first == -1){ //没有后继的边节点
        g->headlist[tar].in = in;
        g->headlist[tar].data = data;
        return 1;
    }

    if(!g->headlist[tar].fnode){ //观察是否已经初始化
        g->headlist[tar].in = in;
        g->headlist[tar].data = data;
    }
    EdgeNode *e = (EdgeNode *)malloc(sizeof(EdgeNode));
    e->data = first;
    e->next = g->headlist[tar].fnode;
    g->headlist[tar].fnode = e;
    return 0;
}
复制代码

执行示例:

posted @   xingoo  阅读(2921)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示