BUPT-homework/semester3/pset6/7-2-拓扑排序.c

185 lines
3.6 KiB
C
Raw Normal View History

2022-11-19 20:33:35 +08:00
// NEEDS REWORKING
#include <stdio.h>
#include <stdlib.h>
#define SIZE 11
typedef struct listNode {
char ID;
struct listNode *next;
} listNode;
typedef struct queue {
listNode **arr;
int back;
int front;
} queue;
listNode *newNode(char ID) {
listNode *new = malloc(sizeof(listNode));
new->ID = ID;
new->next = NULL;
return new;
}
queue *newQueue() {
queue *q = malloc(sizeof(queue));
q->arr = malloc(sizeof(listNode *) * SIZE);
q->back = 0;
q->front = 0;
return q;
}
void appendNode(listNode *node, listNode *new) {
while (node->next != NULL) {
node = node->next;
}
node->next = new;
}
void push(listNode *li, queue *q) { q->arr[q->back++] = li; }
int isEmpty(queue *q) { return (q->front == q->back); }
listNode *getFront(queue *q) { return q->arr[q->front]; }
void pop(queue *q) {
if (!isEmpty(q)) {
q->front++;
}
}
listNode **makeGraph() {
listNode **graph = malloc(sizeof(listNode *) * SIZE);
// initialize graph
int count = 0;
graph[count++] = newNode('S');
for (; count < 10; count++) {
graph[count] = newNode(count + 'A' - 1);
}
graph[count++] = newNode('T');
appendNode(graph[0], newNode('A'));
appendNode(graph[0], newNode('D'));
appendNode(graph[0], newNode('G'));
appendNode(graph[1], newNode('B'));
appendNode(graph[1], newNode('E'));
appendNode(graph[2], newNode('C'));
appendNode(graph[3], newNode('T'));
appendNode(graph[4], newNode('A'));
appendNode(graph[4], newNode('E'));
appendNode(graph[5], newNode('C'));
appendNode(graph[5], newNode('F'));
appendNode(graph[5], newNode('I'));
appendNode(graph[6], newNode('C'));
appendNode(graph[6], newNode('T'));
appendNode(graph[7], newNode('D'));
appendNode(graph[7], newNode('E'));
appendNode(graph[7], newNode('H'));
appendNode(graph[8], newNode('E'));
appendNode(graph[8], newNode('I'));
appendNode(graph[9], newNode('F'));
appendNode(graph[9], newNode('T'));
return graph;
}
int ch2digit(char ch) {
if (ch == 'S') {
return 0;
} else if (ch == 'T') {
return 10;
} else {
return ch - 'A' + 1;
}
}
int *getIndegree(listNode **g) {
int *inDegree = malloc(sizeof(int) * SIZE);
for (int i = 0; i < SIZE; i++) { // init to 0
inDegree[i] = 0;
}
for (int i = 0; i < SIZE; i++) {
listNode *ptr = g[i]->next;
while (ptr != NULL) {
inDegree[ch2digit(ptr->ID)]++;
ptr = ptr->next;
}
}
// for (int i = 0; i < SIZE; i++) {
// printf("%c: %d\n", g[i]->ID, inDegree[i]);
// }
return inDegree;
}
void topoSort(listNode **g) {
queue *q = newQueue();
int visited[SIZE] = {};
int *inDegree = getIndegree(g);
for (int count = 0; count < SIZE; count++) {
for (int i = 0; i < SIZE; i++) {
if (inDegree[i] == 0 && visited[i] == 0) {
// printf("pushing: %c\n", g[i]->ID);
push(g[i], q);
visited[i] = 1;
}
}
listNode *tmp;
while (!isEmpty(q)) {
tmp = getFront(q);
pop(q);
printf("%c,", tmp->ID);
tmp = g[ch2digit(tmp->ID)]->next;
while (tmp != NULL) {
if (--inDegree[ch2digit(tmp->ID)] == 0 &&
visited[ch2digit(tmp->ID)] == 0) {
push(tmp, q);
visited[ch2digit(tmp->ID)] = 1;
}
tmp = tmp->next;
}
}
}
}
void deleteEdge(listNode **g, char src, char dist) {
listNode *ptr = g[ch2digit(src)];
while (ptr != NULL && ptr->next != NULL) {
if (ptr->next->ID == dist) {
ptr->next = ptr->next->next;
}
ptr = ptr->next;
}
}
int main(void) {
queue *q = newQueue();
listNode **g = makeGraph();
char src, dist;
scanf("%c,%c", &src, &dist);
deleteEdge(g, src, dist);
topoSort(g);
return 0;
}