拓扑排序c语言实现第一关:拓扑排序(课程选课合理建议) 要求:分析专业的课程先后修关系拓扑图,设计结构存储课程先后修关系,并使用拓扑排序算法,给出一种合理的课程选修顺序建议。
时间: 2024-12-19 15:08:09 浏览: 11
Python实现拓扑排序:深入理解与代码实践
拓扑排序是一种对有向无环图(DAG)进行线性排序的算法,使得对于每一条有向边 \(uv\),顶点 \(u\) 在排序中都在顶点 \(v\) 之前。拓扑排序在课程选课问题中非常有用,因为它可以帮助我们确定课程学习的顺序。
下面是一个使用C语言实现拓扑排序的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#define MAX_COURSES 100
// 定义邻接表节点结构
typedef struct AdjListNode {
int dest;
struct AdjListNode* next;
} AdjListNode;
// 定义图结构
typedef struct Graph {
int numVertices;
AdjListNode** adjLists;
} Graph;
// 定义栈结构
typedef struct Stack {
int items[MAX_COURSES];
int top;
} Stack;
// 创建图
Graph* createGraph(int vertices) {
Graph* graph = (Graph*)malloc(sizeof(Graph));
graph->numVertices = vertices;
graph->adjLists = (AdjListNode**)malloc(vertices * sizeof(AdjListNode*));
for (int i = 0; i < vertices; i++)
graph->adjLists[i] = NULL;
return graph;
}
// 创建邻接表节点
AdjListNode* newAdjListNode(int dest) {
AdjListNode* newNode = (AdjListNode*)malloc(sizeof(AdjListNode));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}
// 添加边
void addEdge(Graph* graph, int src, int dest) {
AdjListNode* newNode = newAdjListNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;
}
// 创建栈
Stack* createStack() {
Stack* stack = (Stack*)malloc(sizeof(Stack));
stack->top = -1;
return stack;
}
// 栈是否为空
int isEmpty(Stack* stack) {
return stack->top == -1;
}
// 入栈
void push(Stack* stack, int item) {
stack->items[++stack->top] = item;
}
// 出栈
int pop(Stack* stack) {
return stack->items[stack->top--];
}
// 拓扑排序
void topologicalSort(Graph* graph) {
Stack* stack = createStack();
int* visited = (int*)malloc(graph->numVertices * sizeof(int));
for (int i = 0; i < graph->numVertices; i++)
visited[i] = 0;
for (int i = 0; i < graph->numVertices; i++) {
if (visited[i] == 0) {
// 深度优先搜索
DFS(graph, i, visited, stack);
}
}
// 打印拓扑排序结果
printf("课程选修顺序建议: ");
while (!isEmpty(stack)) {
printf("%d ", pop(stack));
}
printf("\n");
}
// 深度优先搜索
void DFS(Graph* graph, int vertex, int* visited, Stack* stack) {
visited[vertex] = 1;
AdjListNode* adjList = graph->adjLists[vertex];
while (adjList != NULL) {
if (!visited[adjList->dest])
DFS(graph, adjList->dest, visited, stack);
adjList = adjList->next;
}
push(stack, vertex);
}
int main() {
// 假设有4门课程
int numCourses = 4;
Graph* graph = createGraph(numCourses);
// 添加课程先后修关系
addEdge(graph, 0, 1); // 课程0是课程1的前置课程
addEdge(graph, 0, 2); // 课程0是课程2的前置课程
addEdge(graph, 1, 3); // 课程1是课程3的前置课程
addEdge(graph, 2, 3); // 课程2是课程3的前置课程
// 进行拓扑排序
topologicalSort(graph);
return 0;
}
```
在这个示例中,我们定义了一个图结构来表示课程之间的先后修关系,并通过拓扑排序算法给出了一个合理的课程选修顺序建议。
阅读全文