编写一个程序,判断如下有向图是否是有向无环图,并给出一个拓扑排序序列。用C语言
时间: 2024-12-16 15:27:29 浏览: 11
在C语言中,编写一个判断有向无环图(DAG, Directed Acyclic Graph)并进行拓扑排序的程序通常会涉及到邻接表数据结构和深度优先搜索(DFS)或广度优先搜索(BFS)算法。下面是一个简单的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTEX 100
typedef struct {
int destination;
struct Node* next;
} Edge;
typedef struct Node {
int data;
Edge* edges;
struct Node* next;
} Graph;
Graph* createGraph(int vertices);
void addEdge(Graph* graph, int src, int dest);
int isCyclicUtil(Graph* g, int v, bool visited[], bool recStack[]);
void topologicalSortUtil(Graph* g, int v, int count, int* topoOrder);
// 主函数
int main() {
int numVertices, numEdges;
printf("Enter number of vertices and edges: ");
scanf("%d %d", &numVertices, &numEdges);
Graph* graph = createGraph(numVertices);
for (int i = 0; i < numEdges; ++i) {
int u, v;
printf("Enter edge %d from vertex (%d to %d): ", i + 1, u + 1, v + 1);
scanf("%d %d", &u, &v);
addEdge(graph, u, v);
}
if (!isCyclicUtil(graph, 0, NULL, true)) {
printf("The graph is a DAG.\n");
int topoOrder[MAX_VERTEX] = {0};
topologicalSortUtil(graph, 0, -1, topoOrder);
printf("A possible Topological Sort sequence: ");
for (int i = 0; topoOrder[i] != -1; ++i)
printf("%d ", topoOrder[i]);
} else {
printf("The graph contains a cycle.\n");
}
return 0;
}
// 创建邻接列表表示的图
Graph* createGraph(int vertices) {
Graph* g = (Graph*)malloc(sizeof(Graph));
g->data = vertices;
g->edges = (Edge*)malloc(sizeof(Edge) * vertices);
for (int i = 0; i < vertices; ++i) {
g->edges[i].destination = -1;
g->edges[i].next = NULL;
}
return g;
}
// 添加边到图中
void addEdge(Graph* graph, int src, int dest) {
Edge* newEdge = (Edge*)malloc(sizeof(Edge));
newEdge->destination = dest;
newEdge->next = graph->edges[src];
graph->edges[src] = newEdge;
}
// 判断图是否存在环,辅助函数
bool isCyclicUtil(Graph* g, int v, bool visited[], bool recStack[]) {
// 初始化标记和回溯栈
visited[v] = true;
recStack[v] = true;
Edge* currNode = g->edges[v];
while (currNode != NULL) {
int adj = currNode->destination;
if (visited[adj]) {
if (recStack[adj])
return true;
else
continue;
}
if (isCyclicUtil(g, adj, visited, recStack))
return true;
currNode = currNode->next;
}
recStack[v] = false;
return false;
}
// 拓扑排序
void topologicalSortUtil(Graph* g, int v, int count, int* topoOrder) {
if (count == -1) {
count = 0;
for (int i = 0; i < g->data; ++i)
if (g->edges[i].destination == -1)
topologicalSortUtil(g, i, count, topoOrder);
} else {
topoOrder[count++] = v;
Edge* node = g->edges[v];
while (node != NULL) {
int adj = node->destination;
if (adj != -1)
topologicalSortUtil(g, adj, count, topoOrder);
node = node->next;
}
}
}
```
在这个例子中,我们首先创建一个图,然后添加边,接着用`isCyclicUtil`函数检查是否有环,如果有则返回错误信息;如果没有,则通过`topologicalSortUtil`函数进行拓扑排序。注意这只是一个基础版本,实际应用中可能需要处理更复杂的边界情况。
阅读全文