185 lines
3.6 KiB
C
185 lines
3.6 KiB
C
// 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;
|
|
}
|