数据结构_图的应用_拓扑排序

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#define MVEX 10
#define size sizeof(Arcnode)
#define queue_length 10

typedef struct Arcnode
{
    int name;
    struct Arcnode * next_arcnode;
   // int info //节点的其他信息 譬如权重
}Arcnode;

typedef struct
{
    int name;
    Arcnode * next_arcnode;
}List[MVEX];

typedef struct
{
    int vexnum, arcnum;
    List L;
}Graph;

// 以上是建立图
typedef struct
{
    int *base;
    int head, tail, length;
}Queue; //建立队列


void Creat_Graph(Graph * G)  //构建一个邻接链表 来存储
{
    int i, j, m, n, k;
    Arcnode * p, *q;
    scanf("%d %d", &G->vexnum, &G->arcnum);
    for(i = 0; i < G->vexnum; i++){
        G->L[i].name = i;
        G->L[i].next_arcnode = NULL;
    }
    for(i = 0; i < G->arcnum; i++){
        scanf("%d %d", &m, &n);
        p = (Arcnode *)malloc(size);
        p->next_arcnode = G->L[m].next_arcnode;
        p->name = n;
        G->L[m].next_arcnode = p;
    }
}

void InitStack(Queue * Q)  //初始化一个队列
{
    Q->base = (int *)malloc(queue_length);
    if(!Q->base) exit(5);
    Q->head = Q->tail = 0;
}

int Pop(Queue * Q)   //出队列
{
    int temp;
    if(Q->head == Q->tail) exit(6);
    temp = Q->base[Q->head++];
    return temp;
}

void Push(Queue * Q, int i)  //入队列
{
    if(Q->tail - Q->head > Q->length) exit(7);
    Q->base[Q->tail++] = i;
}

void FindInDegree(Graph G, int indegree[])  //把每个节点对应的入度存储到 indegree数组里
{
    int i, k, mark_num = 0;
    Arcnode * temp;
    for(i = 0; i < G.vexnum; i++){
        indegree[i] = 0;
    }
    for(i = 0; i < G.vexnum; i++){
        temp = G.L[i].next_arcnode;
        while(temp){
            k = temp->name;
            temp = temp->next_arcnode;

            indegree[k]++;
        }
    }
}

bool TopologicalSort(Graph G, int topo[])  //拓扑排序算法
{
    int indegree[G.vexnum], m, temp, i, k;  //先定义一个入度数组indegree;
    Arcnode * p;  
    Queue S;  //定义一个队列 来存储入度为0的节点  加快排序,  以免重复检查入度已经为0的节点
    FindInDegree(G, indegree);  
    InitStack(&S);   //初始话一个队列
    for(i = 0; i < G.vexnum; i++){
        if(indegree[i] == 0) Push(&S, i);
    }  //先把入度为0的放到队列里 
    /* ***************初始化完成开始进行拓扑排序************** */
    m = 0;
    while(S.head != S.tail){
        temp = Pop(&S);
        topo[m++] = temp;   //最先入度为0 的 存入到 topo数组里  最后数组里的值就是  排序完成后的序列
        p = G.L[temp].next_arcnode;
        while(p){  //寻找以temp节点为出度的   对应的相应的入度的节点  并且相应的入度节点的入度减一。
            k = p->name;
            indegree[k]--;
            if(indegree[k] == 0) Push(&S, k);
            p = p->next_arcnode;
        }
    }
    if(m < G.vexnum) return "ERROR";
    else return "OK";
}

int main()
{
    Graph G;
    int topo[queue_length], i;
    Creat_Graph(&G);
    TopologicalSort(G, topo);
    for(i = 0; i < G.vexnum; i++)  //输出拓扑排序的序列(序列不唯一,一旦同时有多个入度为0的节点 那么这些节点的序列任意)
        printf("%d", topo[i]);  
    return 0;
}
//例子:
/*
6 8
0 1
0 2
0 3
3 4
5 4
2 4
2 1
5 3
*/

实验案例如下:

共6个节点分别为(0, 1, 2, 3, 4, 5)

关系为:

0-->1

0-->2

0-->3

3-->4

5-->4

2-->4

2-->1

5-->3

运行结果为:



猜你喜欢

转载自blog.csdn.net/ltrbless/article/details/80502792