拓扑排序(C语言 邻接表)

来源:互联网 发布:c语言主函数参数 编辑:程序博客网 时间:2024/05/27 08:14

数据结构

//数据结构typedef struct Side//边{    int toVertex;//边指向的点    struct side *next;}Side,*sLink;typedef struct Vertex//顶点{    int data;    sLink first;//第一个边}Vertex,AdjList[20];typedef struct Graph//图{    AdjList adj;//顶点数组,注意不是指针,用.不用->    int n,v;//顶点数,边数}Graph,*gLink;


创建图

//创建void createGraph(gLink g){    int n,v,data;    printf("请输入顶点数与边数");    scanf("%d %d",&n,&v);    g->n = n;    g->v = v;    int i;    for(i=0;i<n;i++)    {        printf("请输入顶点%d权值",i);        scanf("%d",&data);        g->adj[i].data = data;        g->adj[i].first = NULL;    }    printf("请输入边信息");    int v1,v2;    for(i=0;i<v;i++)    {        scanf("%d %d",&v1,&v2);        sLink s = (sLink)malloc(sizeof(Side));        s->toVertex = v2;        s->next = g->adj[v1].first;        g->adj[v1].first = s;    }}

拓扑排序

求每个点的初始入度

遍历邻接表,由于每一条边指向一个顶点,所以找到一条边则为其指向的顶点入度加1。

a为存放入度的数组,下标与顶点下标对应

void inDegree(gLink g,int *a){    int i;    for(i=0;i<g->n;i++)    {        a[i]=0;    }    for(i=0;i<g->n;i++)    {        sLink s = g->adj[i].first;        while(s)        {            a[s->toVertex]++;            s = s->next;        }    }}

拓扑排序

1、求初始入度

2、将最初入度为0的顶点入队

3、队列不为空则循环

3.1、出队一个顶点,输出值

3.2、将其所有边指向的顶点入度减1,若减完后有顶点入度变为0,则入队

3.3、回到3

//拓扑排序void tuopu(gLink g){    Vertex queue[10];    int front=0, rear=0;    int a[g->n];    inDegree(g,a);    int i;    for(i=0;i<g->n;i++)    {        if(!a[i])        {            queue[rear++] = g->adj[i];        }    }    while(front!=rear)    {        Vertex v = queue[front++];        printf("%d,",v.data);        sLink s = v.first;        while(s)        {            if(!--a[s->toVertex])            {                queue[rear++] = g->adj[s->toVertex];            }            s = s->next;        }    }}

主函数

int main(){    gLink g = (gLink)malloc(sizeof(Graph));    createGraph(g);    tuopu(g);    return 0;}

原创粉丝点击