c语言计算拓扑排序

2022-04-28  本文已影响0人  一路向后

1.源码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

struct List {
    int w;
    struct List *next;
    struct List *last;
};

struct Queue {
    int v;
    struct Queue *next;
    struct Queue *last;
};

void ListPush(struct List **list, int w)
{
    struct List *last = (struct List *)malloc(sizeof(struct List));

    memset(last, 0x00, sizeof(struct List));

    last->w = w;

    if((*list) == NULL)
    {
        *list = last;

        (*list)->next = NULL;
        (*list)->last = last;

        return;
    }

    if((*list)->next == NULL)
    {
        (*list)->next = last;
    }

    (*list)->last->next = last;
    (*list)->last = last;
}

void ListPop(struct List **list)
{
    struct List *top = (*list);

    if(list == NULL || *list == NULL)
    {
        return;
    }

    if((*list)->next == NULL)
    {
        free(*list);

        *list = NULL;

        return;
    }

    (*list) = (*list)->next;

    (*list)->last = top->last;

    free(top);
}

int ListFront(const struct List *list)
{
    if(list == NULL)
    {
        return -1;
    }

    return list->w;
}

char ListIsEmpty(const struct List *list)
{
    if(list == NULL)
    {
        return 1;
    }

    return 0;
}

void ListFree(struct List **list)
{
    if(!list)
    {
        return;
    }

    while(!ListIsEmpty(*list))
    {
        ListPop(list);
    }
}

void QueuePush(struct Queue **queue, int v)
{
    struct Queue *last = NULL;

    last = (struct Queue *)malloc(sizeof(struct Queue));

    memset(last, 0x00, sizeof(struct Queue));

    last->v = v;

    if((*queue) == NULL)
    {
        *queue = last;

        (*queue)->next = NULL;
        (*queue)->last = last;

        return;
    }

    if((*queue)->next == NULL)
    {
        (*queue)->next = last;
    }

    (*queue)->last->next = last;
    (*queue)->last = last;
}

void QueuePop(struct Queue **queue)
{
    struct Queue *top = NULL;

    if(queue == NULL || *queue == NULL)
    {
        return;
    }

    top = (*queue);

    if((*queue)->next == NULL)
    {
        free(*queue);

        *queue = NULL;

        return;
    }

    (*queue) = (*queue)->next;

    (*queue)->last = top->last;

    free(top);
}

int QueueFront(const struct Queue *queue)
{
    if(queue == NULL)
    {
        return -1;
    }

    return queue->v;
}

char QueueIsEmpty(const struct Queue *queue)
{
    if(queue == NULL)
    {
        return 1;
    }

    return 0;
}

void QueueFree(struct Queue **queue)
{
    while(!QueueIsEmpty(*queue))
    {
        QueuePop(queue);
    }
}

void GraphInit(struct List ***adj, int **indegree, int V)
{
    int i;

    (*adj) = (struct List **)malloc(sizeof(struct List **)*V);
    (*indegree) = (int *)malloc(sizeof(int *)*V);

    for(i=0; i<V; i++)
    {
        (*adj)[i] = NULL;
        (*indegree)[i] = 0;
    }
}

void GraphFree(struct List ***adj, int **indegree, int n)
{
    int i;

    for(i=0; i<n; i++)
    {
        ListFree((*adj)+i);
    }

    free(*adj);
    free(*indegree);

    *adj = NULL;
    *indegree = NULL;
}

void GraphAddEdge(struct List **adj, int *indegree, int v, int w)
{
    ListPush(adj+v, w);
    ++indegree[w];
}

char GraphTopoLogicSort(struct List **adj, int *indegree, int V, struct Queue **q, struct Queue **r)
{
    struct List **u = NULL;
    struct List *p = NULL;
    int i;

    /*将所有入度为零的顶点入队*/
    for(i=0; i<V; i++)
    {
        if(indegree[i] == 0)
        {
            QueuePush(q, i);
        }
    }

    /*记录当前已经输出的顶点数*/
    int count = 0;

    while(!QueueIsEmpty(*q))
    {
        int v = QueueFront(*q);

        QueuePop(q);
        QueuePush(r, v);

        ++count;

        if(v == -1)
        {
            break;
        }

        u = adj + v;
        p = *u;

        i = 0;

        /*将所有v指向的顶点的入度减1*/
        while(p != NULL)
        {
            if(!(--indegree[p->w]))
            {
                /*若度为0则入栈*/

                QueuePush(q, p->w);
                        }

            i++;

            p = p->next;
                }
        }

    if(count < V)
    {
        return 0;
    }

    return 1;
}

int main()
{
    struct List **adj = NULL;
    struct Queue *p = NULL;
    struct Queue *q = NULL;
    int *indegree = NULL;
    int n = -1;
    int m = -1;
    int a = -1;
    int b = -1;
    int c = 0;
    int i = 0;
    int u = -1;

    scanf("%d %d", &n, &m);

    if(m < 1 || n < 1)
    {
        return -1;
    }

    GraphInit(&adj, &indegree, n);

    for(i=0; i<m; i++)
    {
        a = -1;
        b = -1;

        scanf("%d %d", &a, &b);

        if(a < 1 || b < 1)
        {
            continue;
        }

        GraphAddEdge(adj, indegree, a-1, b-1);
    }

    c = GraphTopoLogicSort(adj, indegree, n, &p, &q);

    if(QueueIsEmpty(q) || c == 0)
    {
        printf("-1\n");
    }
    else
    {
        u = QueueFront(q) + 1;

        printf("%d", u);

        QueuePop(&q);

        while(!QueueIsEmpty(q))
        {
            u = QueueFront(q) + 1;

            printf(" %d", u);

            QueuePop(&q);
        }

        printf("\n");
    }

    GraphFree(&adj, &indegree, n);

    return 0;
}

2.编译源码

$ gcc -o test test.c -std=c89

3.运行及其结果

$ ./test
5 4
1 2
2 3
3 4
4 5
1 2 3 4 5
上一篇 下一篇

猜你喜欢

热点阅读