我这里的拓扑排序为啥没有输出来?

我这里的拓扑排序为啥没有输出来?

img


完整代码:
KeyPath.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define MAXV 20
#define INF 32767
typedef struct ANode
{
    int adjvex;
    struct ANode* nextarc;
    int weight;
}ArcNode;

typedef struct
{
    ArcNode* firstarc;
    int count;
}VNode;

typedef struct
{
    VNode adjlist[MAXV];
    int n, e;
}AdjGraph;

void CreateGraph(AdjGraph*& G, int A[][MAXV], int n, int e);

void KeyPath(AdjGraph* G);

KeyPath.cpp:

#include"KeyPath.h"
void CreateGraph(AdjGraph*& G, int A[][MAXV], int n, int e)
{
    G = (AdjGraph*)malloc(sizeof(AdjGraph));
    G->n = n;
    G->e = e;
    int i = 0;
    int j = 0;
    ArcNode* p = NULL;
    for (i = 0; i < G->n; i++)
    {
        G->adjlist[i].firstarc = NULL;
        for (j = 0; j < G->n; j++)
        {
            if (A[i][j] != 0 && A[i][j] != INF)
            {
                p = (ArcNode*)malloc(sizeof(ArcNode));
                p->adjvex = j;
                p->weight = A[i][j];
                p->nextarc = G->adjlist[i].firstarc;
                G->adjlist[i].firstarc = p;
            }
        }
    }
}

void TopSort(AdjGraph* G, int topsort[])
{
    int i = 0;
    ArcNode* p = NULL;
    int St[MAXV];
    int top = -1;
    int k = -1;
    for (i = 0; i < G->n; i++)
    {
        G->adjlist[i].count = 0;
    }
    for (i = 0; i < G->n; i++)
    {
        p = G->adjlist[i].firstarc;
        while (p != NULL)
        {
            G->adjlist[p->adjvex].count++;
            p = p->nextarc;
        }
    }
    for (i = 0; i < G->n; i++)
    {
        if (G->adjlist[i].count == 0)
        {
            St[++top] = i;
        }
    }
    while (top > -1)
    {
        i = St[top--];
        topsort[++k] = i;
        p = G->adjlist[i].firstarc;
        while (p != NULL)
        {
            G->adjlist[p->adjvex].count--;
            if (G->adjlist[p->adjvex].count == 0)
            {
                St[++top] = p->adjvex;
            }
            p = p->nextarc;
        }
    }
    if (k < G->n)
        return;
    else
    {
        printf("拓扑序列为:\n");
        for (i = 0; i < G->n; i++)
            printf("%c ", (char)(topsort[i] + 'A'));
        printf("\n");
    }
}

void KeyPath(AdjGraph* G)
{
    int ee[MAXV] = { 0 };
    int el[MAXV];
    int ve;
    int vl;
    int topsort[MAXV];
    TopSort(G, topsort);
    int lnode = topsort[0];
    int enode = topsort[G->n - 1];
    int i = 0;
    ArcNode* p = NULL;
    for (i = 0; i < G->n; i++)
    {
        p = G->adjlist[i].firstarc;
        while (p != NULL)
        {
            if (p->weight + ee[i] > ee[p->adjvex])
            {
                ee[p->adjvex] = p->weight + ee[i];
            }
            p = p->nextarc;
        }
    }
    for (i = 0; i < G->n; i++)
    {
        el[i] = ee[enode];
    }
    for (i = G->n - 2; i >= 0; i--)
    {
        p = G->adjlist[i].firstarc;
        while (p != NULL)
        {
            //if (ee[i] - p->weight < el[i])
            if (el[i] - p->weight < el[i])
            {
                el[i] = ee[i] - p->weight;
            }
            p = p->nextarc;
        }
    }
    for (i = 0; i < G->n; i++)
    {
        p = G->adjlist[i].firstarc;
        while (p != NULL)
        {
            ve = ee[i];
            vl = el[p->adjvex] - p->weight;
            if (ve == vl)
            {
                printf("%3d%3d%3d\n", i, p->adjvex, p->weight);
            }
            p = p->nextarc;
        }
    }
}

test.cpp:

#include"KeyPath.h"
int main()
{
    int A[MAXV][MAXV] = {
    {0,   6,  4,   5,  INF, INF, INF, INF, INF},
    {INF, 0,  INF, INF, 1, INF, INF, INF, INF},
    {INF, INF, 0,  INF, 1, INF, INF, INF, INF},
    {INF, INF, INF, 0, INF, INF, INF, 2, INF},
    {INF, INF, INF, INF, 0,  9,   7, INF, INF},
    {INF, INF, INF, INF, INF, 0, INF, INF, 2},
    {INF, INF, INF, INF, INF, INF, 0, INF, 4},
    {INF, INF, INF, INF, INF, INF, INF, 0, 4},
    {INF, INF, INF, INF, INF, INF, INF, INF, 0} };
    int n = 9, e = 11; 
    AdjGraph* G;
    CreateGraph(G, A, n, e);
    KeyPath(G);
    return 0;
}

首先,我注意到你的TopSort函数没有返回值,但是在一些情况下你试图返回(return;),这可能会引起编译器警告。此外,我建议在main函数中添加对图是否为空的检查,确保图已经被正确创建。

然后,有一个关键的问题在于拓扑排序函数TopSort()。在该函数中,如果顶点数量k小于图的顶点数量G->n,函数就会直接返回,这意味着如果图中存在环,函数将不会进行任何输出。

在你的代码中,似乎在所有情况下,TopSort()函数都没有对外输出结果。这可能是因为你的图G存在环。由于拓扑排序只能在有向无环图(DAG)上进行,因此,如果你的图存在环,拓扑排序将失败。

为了解决这个问题,你需要检查输入的图是否存在环。你可以使用深度优先搜索(DFS)或并查集等方法来检测图中是否存在环。如果存在环,你需要修改输入的图,使其成为一个DAG,然后再进行拓扑排序。

最后,在KeyPath()函数中,我注意到这一行可能有误:

el[i] = ee[i] - p->weight;

应改为:

el[p->adjvex] = el[i] - p->weight;

这是因为你要更新目标顶点p->adjvex的最晚开始时间,而非源顶点i

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    回答:

    我可以在多种编程语言中进行拓扑排序的实现,如C++, Python, Java,等等。其中,C++和Python是我最常用的语言。

    以下是一个C++版本的拓扑排序代码片段:

    #include <iostream>
    #include <vector>
    #include <queue>
    
    using namespace std;
    
    vector<vector<int>> adj;
    vector<int> indegrees;
    
    void topsort () {
        queue<int> q;
        for(int i = 0; i < indegrees.size(); ++i) {
            if (indegrees[i] == 0) q.push(i);
        }
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            cout << u << " ";
            for(int v : adj[u]) {
                if (--indegrees[v] == 0)
                    q.push(v);
            }
        }
    }
    
    int main() {
        int n, m;
        cin >> n >> m;
        adj.resize(n, vector<int>());
        indegrees.resize(n, 0);
        for(int i = 0; i < m; ++i) {
            int a, b;
            cin >> a >> b;
            adj[a].push_back(b);
            ++indegrees[b];
        }
        topsort();
        return 0;
    }
    

    这段代码实现了拓扑排序的基本流程,包括顶点入度的计算,队列的初始化,以及遍历所有点并更新入度的过程。可以根据具体需求修改和优化。

    对于这段代码,可能会存在一些运行时错误,例如输入格式不正确、给定图不是一个有向无环图等。可以采用良好的异常处理、调试方法等来解决这些问题。

    除了基本的拓扑排序算法,我还尝试过一些其他算法,例如深度优先遍历DFS和关键路径算法。在不同的场景下,这些算法可能会更加适合。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^