123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- 18-Jul-84 02:10:28-EDT,3724;000000000001
- Received: from MIT-MC by MIT-OZ via Chaosnet; 18 Jul 84 02:10-EDT
- Received: from ucbernie.ARPA by UCB-VAX.ARPA (4.28/4.31)
- id AA08177; Tue, 17 Jul 84 22:46:34 pdt
- Received: by ucbernie.ARPA (4.28/4.30)
- id AA10610; Tue, 17 Jul 84 22:47:11 pdt
- Date: Tue, 17 Jul 84 22:47:11 pdt
- From: phr%ucbernie@Berkeley (Paul Rubin)
- Message-Id: <8407180547.AA10610@ucbernie.ARPA>
- To: rms@oz@mc
- Subject: I should be able to get this to run faster sometime
- #include <stdio.h>
- #define MAXLEN 1000
- #define HASHSIZE 10007 /* for now, MAX no. of distinct vertices */
- /*
- * tsort - topological sort. Linear time algorithm
- * suggested by Avi Wigderson.
- * --phr, 16 July 1984
- */
- struct node {
- char *name;
- int indegree; /* number of predecessors */
- struct nodelist *successors; /* successors in graph */
- struct node *next;
- struct node *back;
- };
- struct nodelist {
- struct node *id;
- struct nodelist *next;
- };
- typedef struct node NODE;
- typedef struct nodelist NLIST;
- NODE *graph = NULL;
- int nnodes = 0;
- main(argc, argv)
- int argc;
- char **argv;
- {
- int n = 0;
- NODE *lookup();
- register NODE *p, *q;
- NLIST *t;
- FILE *ifile = stdin;
- char from[MAXLEN], to[MAXLEN];
- if (argc > 1 && (ifile = fopen(argv[1], "r")) == NULL) {
- perror(argv[1]);
- exit(1);
- }
- while (fscanf(ifile, "%s %s", from, to) > 0) {
- p = lookup(from);
- q = lookup(to);
- if (p == q)
- continue;
- /* actually this scan might be taking more time than it saves */
- for (t = p->successors; t != NULL; t = t->next)
- if (t->id == q)
- break;
- if (t == NULL) { /* q not already on successor list */
- t = (NLIST *) malloc(sizeof (NLIST));
- t->id = q;
- t->next = p->successors;
- p->successors = t;
- ++q->indegree;
- }
- } /* each node now has a correct predecessor count and
- successor list. */
- if (nnodes == 0)
- exit(0);
- /* next, move all the root nodes to the head of the list */
- for (p = graph; p != NULL; p = p->next) {
- q = p->next;
- if (q == NULL)
- break;
- if (q->indegree == 0) {
- p->next = q->next;
- q->next = graph;
- graph = q;
- }
- }
- /* now turn the list into a doubly linked list */
- for (p = graph; p->next != NULL; p = p->next)
- p->next->back = p;
- graph->back = NULL;
- /* output */
- for (p = graph; p != NULL; nnodes--) {
- if (p->indegree != 0) {
- fprintf(stderr, "tsort: graph is circular\n");
- exit (1);
- }
- printf("%s\n", p->name);
- t = p->successors;
- p = p->next;
- for (; t != NULL; t = t->next) {
- q = t->id;
- if (--q->indegree == 0) {
- /* move new root to head of list. q->back->next will not
- be null because q had indegree > 0. */
- if (q == p) /* it's already at head */
- continue;
- q->back->next = q->next;
- if (q->next != NULL)
- q->next->back = q->back;
- q->next = p;
- p->back = q;
- p = q;
- p->back = NULL;
- }
- }
- }
- if (n != 0) {
- fprintf(stderr, "tsort: graph has cycles\n");
- exit (1);
- }
- exit (0);
- }
- NODE *lookup(name)
- char *name;
- {
- char *newstring();
- static NODE *hashtab[HASHSIZE];
- register NODE *p;
- register int i;
- for (i = hashf(name); hashtab[i] != NULL; i = (i+1)%HASHSIZE)
- if (strcmp(hashtab[i]->name, name) == 0)
- return hashtab[i];
- p = hashtab[i] = (NODE *) calloc(1, sizeof (NODE));
- p->name = newstring(name);
- p->next = graph;
- graph = p;
- nnodes++;
- return p;
- }
- static int hashf(s)
- register char *s;
- {
- register int r = 0;
- while (*s)
- r = (r << 1) + *s++;
- r &= ~0x80000000; /* make r nonnegative */
- return r % HASHSIZE;
- }
- char *newstring(s)
- char *s;
- {
- char *p = (char *) malloc(strlen(s) + 1);
- strcpy(p, s);
- return p;
- }
|