Data Structure --- Topology Sorting in C Language AOV Diagram
// Topological sorting of Directed Graphs // Yang Xin # include
# Include
# Include
# Define MAX_NAME 3 # define MAX_VERTEX_NUM 20 typedef int InfoType; // storage network weight typedef char VertexType [MAX_NAME]; // string type typedef enum {DG, DN, AG, AN} GraphKind; // {directed graph, directed graph} // The graph's adjacent table stores typedef struct ArcNode {int adjvex; // struct ArcNode * nextarc of the vertex to which the arc points; // InfoType * info; // weight pointer of the network} ArcNode; typedef struct VNode {VertexType data; // vertex information ArcNode * firstarc; // address of the first table node, pointing to the first arc pointer to the vertex} VNode, AdjList [MAX_V ERTEX_NUM]; // header node typedef struct {AdjList vertices; int vexnum, arcnum; // Number of the current vertex and arc of the graph int kind; // type flag of the graph} ALGraph; // If vertex u exists in G, the position of the vertex in the graph is returned.-1int LocateVex (ALGraph G, VertexType u) {int I; for (I = 0; I <G. vexnum; ++ I) {if (strcmp (u, G. vertices [I]. data) = 0) return I; return-1 ;}// uses the storage structure of the adjacent table to construct a graph G without relevant information (use a function to construct four graphs) int CreateGraph (ALGraph * G) {int I, j, k; int w; // weight VertexType va, vb; ArcNode * p; printf (enter the graph type (directed Figure: 0, Directed Network: 1, undirected graph: 2, Directed Network: 3) :); scanf (% d, & (* G ). kind); printf (enter the number of vertices and edges of the graph: (separated by spaces):); scanf (% d, & (* G ). vexnum, & (* G ). arcnum); printf (enter % d vertex values (less than % d characters):, (* G ). vexnum, MAX_NAME); for (I = 0; I <(* G ). vexnum; ++ I) // construct the vertex vector {scanf (% s, (* G ). vertices [I]. data); (* G ). vertices [I]. firstarc = NULL;} if (* G ). kind = 1 | (* G ). kind = 3) // net {printf (Please input the weight of each arc (edge) in sequence, arc tail and arc header (separated by space ):);} else // figure {printf (Please input the arc tail and arc header of each arc (edge) sequentially (separated by spaces ):) ;}For (k = 0; k <(* G ). arcnum; ++ k) {if (* G ). kind = 1 | (* G ). kind = 3) scanf (% d % s, & w, va, vb); elsescanf (% s, va, vb ); I = LocateVex (* G, va); // arc tail j = LocateVex (* G, vb); // arc header p = (ArcNode *) malloc (sizeof (ArcNode); p-> adjvex = j; if (* G ). kind = 1 | (* G ). kind = 3) {p-> info = (int *) malloc (sizeof (int); * (p-> info) = w ;} else {p-> info = NULL;} p-> nextarc = (* G ). vertices [I]. firstarc; // Insert the header (* G ). vertices [I]. Firstarc = p; if (* G ). kind> = 2) // returns the second table node {p = (ArcNode *) malloc (sizeof (ArcNode); p-> adjvex = I; if (* G ). kind = 3) {p-> info = (int *) malloc (sizeof (int); * (p-> info) = w ;} else {p-> info = NULL;} p-> nextarc = (* G ). vertices [j]. firstarc; // Insert the header (* G ). vertices [j]. firstarc = p ;}} return 1 ;}// the Gvoid Display (ALGraph G) {int I; ArcNode * p; switch (G. kind) {case DG: printf (Directed Graph); break; case DN: printf (Directed Network); break; c Ase AG: printf (undirected graph); break; case AN: printf (undirected network);} printf (% d vertices:, G. vexnum); for (I = 0; I <G. vexnum; ++ I) {printf (% s, G. vertices [I]. data);} printf (% d arc (edge):, G. arcnum); for (I = 0; I <G. vexnum; I ++) {p = G. vertices [I]. firstarc; while (p) {if (G. kind <= 1) {printf (% s-> % s, G. vertices [I]. data, G. vertices [p-> adjvex]. data); if (G. kind = DN) printf (: % d, * (p-> info);} else {if (I <p-> adjvex) {printf (% s -- % s, G. vertices [I ]. Data, G. vertices [p-> adjvex]. data); if (G. kind = AN) printf (: % d, * (p-> info) ;}} p = p-> nextarc;} printf ();}} // calculate the vertex input void FindInDegree (ALGraph G, int indegree []) {int I; ArcNode * p; // assign the initial value for (I = 0; I <G. vexnum; I ++) {indegree [I] = 0 ;}for (I = 0; I <G. vexnum; I ++) {p = G. vertices [I]. firstarc; while (p) {indegree [p-> adjvex] ++; p = p-> nextarc ;}}// stack type typedef int SElemType; # define STACK_INIT_SIZE 10 // initial storage space allocation # d Efine STACKINCREMENT 2 // storage space allocation increment // The sequential storage structure of the stack indicates typedef struct SqStack {SElemType * base; // The base address SElemType * top; // The stack top pointer int stacksize; // currently allocated bucket} SqStack; // construct an empty stack int InitStack (SqStack * S) {// allocate a specified size of storage space (* S) to the bottom of the stack ). base = (SElemType *) malloc (STACK_INIT_SIZE * sizeof (SElemType); if (! (* S ). base) exit (0); (* S ). top = (* S ). base; // the bottom of the stack is the same as the top pointer of the stack (* S ). stacksize = STACK_INIT_SIZE; return 1;} // if Stack S is empty (the bottom pointer of the stack is the same as the top pointer of the stack), 1 is returned; otherwise, 0 int StackEmpty (SqStack S) is returned) {if (S. top = S. base) return 1; elsereturn 0;} // insert element e to the new stack top element int Push (SqStack * S, SElemType e) {if (* S ). top-(* S ). base> = (* S ). stacksize) {(* S ). base = (SElemType *) realloc (* S ). base, (* S ). stacksize + STACKINCREMENT) * sizeof (SElemType); if (! (* S ). base) exit (0); (* S ). top = (* S ). base + (* S ). stacksize; (* S ). stacksize + = STACKINCREMENT;} * (* S ). top) ++ = e; return 1 ;}// if the stack is not empty, delete the S stack top element and return its value with e, and return 1, otherwise, return 0int Pop (SqStack * S, SElemType * e) {if (* S ). top = (* S ). base) {return 0;} * e = * -- (* S ). top; return 1;} // G of the directed graph uses the storage structure of the adjacent table. If G has no loop, a topology of the vertex of G is output. int TopologicalSort (ALGraph G) {int I, k, count, indegree [MAX_VERTEX_NUM]; SqStack S; ArcNode * p; FindInDegree (G, indegr Ee); InitStack (& S); for (I = 0; I <G. vexnum; ++ I) {if (! Indegree [I]) Push (& S, I); count = 0; // the stack is not empty while (! StackEmpty (S) {Pop (& S, & I); printf (% s, G. vertices [I]. data); // output vertex I and count + + count; // The inbound degrees of each adjacent vertex of vertex I are reduced by 1for (p = G. vertices [I]. firstarc; p = p-> nextarc) {k = p-> adjvex; if (! (-- Indegree [k]) // if the inbound degree is reduced to 0, the inbound Push (& S, k) ;}} if (count <G. vexnum) {printf (this directed graph has a loop); return 0 ;}else {printf (a topological sequence !!);}}} Int main () {ALGraph f; printf (select directed graph); CreateGraph (& f); Display (f); TopologicalSort (f); return 0 ;}
Result: