Data Structure --- using c language to store and represent the graph's adjacent table --- using c

Source: Internet
Author: User

Data Structure --- using c language to store and represent the graph's adjacent table --- using c

// Map array (Adjacent matrix) Storage representation # include <stdio. h> # include <stdlib. h> # include <string. h> # define MAX_NAME 3 // the maximum length of the vertex string + 1 # define MAX_VERTEX_NUM 20 typedef int InfoType; // the weight of the stored Network: typedef char VertexType [MAX_NAME]; // string type typedef enum {DG, DN, AG, AN} GraphKind; // {directed graph, directed graph, undirected graph, undirected net} int visited [MAX_VERTEX_NUM]; // access flag array void (* VisitFunc) (char * v); // function variable typedef struct ArcNode {int adjvex; // The Position of the vertex pointed to by the arc struct ArcNode * Nextarc; // The InfoType * info pointer to the next arc; // The weight pointer of the network} ArcNode; // table node typedef struct VNode {VertexType data; // vertex information ArcNode * firstarc; // address of the first table node pointing to the first arc pointer attached to the vertex} VNode, AdjList [MAX_VERTEX_NUM]; // header node typedef struct {AdjList vertices; int vexnum, arcnum; // The number of current vertices and the number of arcs int kind of the graph; // The type mark of the graph} ALGraph; typedef int QElemType; // queue type // Single-Chain queue -- queue chain storage structure typedef struct QNode {QElemType data; // data field struct QNode * next; // pointer Field} QNode, * QueuePtr; typedef struct {QueuePtr front, rear; // The team header pointer. the pointer field points to the team Header element, and the team tail element} LinkQueue; // positioning function // If vertex u exists in G, the vertex is returned in the graph; otherwise,-1 is returned. Int 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;} // create a graph // use the storage structure of the adjacent table, construct graph G without relevant information (use a function to construct four types of graphs ). Int CreateGraph (ALGraph * G) {int I, j, k; int w; // weight VertexType va, vb; ArcNode * p; printf ("Enter the graph type (directed graph: 0, directed graph: 1, directed graph: 2, directed graph: 3): \ n"); scanf ("% d ", & (* G ). kind); printf ("Enter the number of vertices and edges of the graph: (Space) \ n"); scanf ("% d", & (* G ). vexnum, & (* G ). arcnum); printf ("Enter % d vertex values (<% d characters): \ n", (* 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 weights, backend and arc headers of each arc (edge) in sequence (separated by spaces ): \ n "); else // figure printf (" Please input the arc tail and arc header of each arc (edge) in sequence (separated by spaces): \ n "); for (k = 0; k <(* G ). arcnum; ++ k) // construct the table node linked list {if (* G ). kind = 1 | (* G ). kind = 3) // scanf ("% d % s", & w, va, vb); else // figure scanf ("% 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) // Net {p-> info = (int *) malloc (sizeof (int); * (p-> info) = w;} elsep-> info = NULL; // Figure 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) // undirected network {p-> info = (int *) malloc (sizeof (int); * (p-> info) = w ;} elsep-> info = NULL; // undirected graph p-> nextarc = (* G ). vertices [j]. firstarc ;// Inserted in the header (* G ). vertices [j]. firstarc = p ;}} return 1 ;}// destroy the Gvoid DestroyGraph (ALGraph * G) {int I; ArcNode * p, * q; for (I = 0; I <(* G ). vexnum; ++ I) {p = (* G ). vertices [I]. firstarc; while (p) {q = p-> nextarc; if (* G ). kind % 2) // net free (p-> info); free (p); p = q ;}} (* G ). vexnum = 0; (* G ). arcnum = 0;} // returns the value of v. VertexType * GetVex (ALGraph G, int v) {if (v> = G. vexnum | v <0) exit (0); return & G. vertices [v]. data;} // new value for v. Int PutVex (ALGraph * G, VertexType v, VertexType value) {int I; I = LocateVex (* G, v); if (I>-1) // v is the vertex of G {strcpy (* G ). vertices [I]. data, value); return 1;} return 0;} // returns the sequence number of the first adjacent vertex of v. If the vertex is not adjacent to the vertex in G,-1 is returned. Int FirstAdjVex (ALGraph G, VertexType v) {ArcNode * p; int v1; v1 = LocateVex (G, v ); // v1 is the sequence number of vertex v in graph G, p = G. vertices [v1]. firstarc; if (p) return p-> adjvex; elsereturn-1;} // returns the sequence number of the next adjacent vertex of v (relative to w. If w is the last // adjacent contact of v,-1 is returned. Int NextAdjVex (ALGraph G, VertexType v, VertexType w) {ArcNode * p; int v1, w1; v1 = LocateVex (G, v ); // v1 is the sequence number of vertex v in graph G w1 = LocateVex (G, w); // w1 is the sequence number of vertex w in graph G p = G. vertices [v1]. firstarc; while (p & p-> adjvex! = W1) // the pointer p is not null and the table node is not w p = p-> nextarc; if (! P |! P-> nextarc) // w is not found or w is the last adjacent point return-1; else // p-> adjvex = w // return the serial number of the next adjacent vertex of v (relative to w), return p-> nextarc-> adjvex ;} // Add a new vertex v in graph G (do not add the arc related to the vertex, and leave it for InsertArc ). Void InsertVex (ALGraph * G, VertexType v) {strcpy (* G ). vertices [(* G ). vexnum]. data, v); // construct a new vertex vector (* G ). vertices [(* G ). vexnum]. firstarc = NULL; (* G ). vexnum ++; // Number of vertices in graph G plus 1} // Delete vertex v and Its Related arc in G. Int DeleteVex (ALGraph * G, VertexType v) {int I, j; ArcNode * p, * q; j = LocateVex (* G, v ); // j is the sequence number of vertex v. if (j <0) // v is not the vertex of graph G. return 0; p = (* G ). vertices [j]. firstarc; // Delete the arc or edge while (p) {q = p; p = p-> nextarc; if (* G ). kind % 2) // network free (q-> info); free (q); (* G ). arcnum --; // The number of arcs or edges minus 1} (* G ). vexnum --; // The number of vertices minus 1 for (I = j; I <(* G ). vexnum; I ++) // forward the vertex after vertex v (* G ). vertices [I] = (* G ). vertices [I + 1]; // deletes the v-based Arc or edge and modifies the vertex of the table node if necessary. Position value for (I = 0; I <(* G ). vexnum; I ++) {p = (* G ). vertices [I]. firstarc; // points to 1st arcs or edges while (p) // An edges with an arc {if (p-> adjvex = j) // An edges with v as the inbound degree. {If (p = (* G ). vertices [I]. firstarc) // The number of nodes to be deleted is 1st {(* G ). vertices [I]. firstarc = p-> nextarc; if (* G ). kind % 2) // net free (p-> info); free (p); p = (* G ). vertices [I]. firstarc; if (* G ). kind <2) // directed (* G ). arcnum --; // arc or edge number minus 1} else {q-> nextarc = p-> nextarc; if (* G ). kind % 2) // net free (p-> info); free (p); p = q-> nextarc; if (* G ). kind <2) // directed (* G ). arcnum --; // arc or edge number minus 1} else {if (p-> adjvex> j) p-> adjvex --; // modify the vertex position value (sequence number) of the table Node) Q = p; p = p-> nextarc ;}} return 1 ;}// add an arc to G <v, w>. If G is undirected, the symmetric arc is also added <w, v>. Int InsertArc (ALGraph * G, VertexType v, VertexType w) {ArcNode * p; int w1, I, j; I = LocateVex (* G, v ); // arc tail or edge number j = LocateVex (* G, w); // if (I <0 | j <0) return 0; (* G ). arcnum ++; // The number of arcs or edges of graph G plus 1 if (* G ). kind % 2) // network {printf ("Enter the arc (edge) % s → % s weight:", v, w); scanf ("% d ", & w1);} p = (ArcNode *) malloc (sizeof (ArcNode); p-> adjvex = j; if (* G ). kind % 2) // net {p-> info = (int *) malloc (sizeof (int); * (p-> info) = w1 ;} elsep-> info = NULL; p -> Nextarc = (* G ). vertices [I]. firstarc; // Insert the header (* G ). vertices [I]. firstarc = p; if (* G ). kind> = 2) // undirected, generate another table node {p = (ArcNode *) malloc (sizeof (ArcNode); p-> adjvex = I; if (* G ). kind = 3) // undirected network {p-> info = (int *) malloc (sizeof (int); * (p-> info) = w1 ;} elsep-> info = NULL; p-> nextarc = (* G ). vertices [j]. firstarc; // Insert the header (* G ). vertices [j]. firstarc = p;} return 1 ;}// Delete the arc in G <v, w>. If G is undirected, delete the symmetric arc <w, v>. Int DeleteArc (ALGraph * G, VertexType v, VertexType w) {ArcNode * p, * q; int I, j; I = LocateVex (* G, v ); // I is the serial number of vertex v (arc tail) j = LocateVex (* G, w); // j is the vertex w (ARC header) if (I <0 | j <0 | I = j) return 0; p = (* G ). vertices [I]. firstarc; // p points to the first arc of vertex v while (p & p-> adjvex! = J) // p is not empty and the arc referred to is not the arc to be deleted <v, w >{// p points to the next arc q = p; p = p-> nextarc ;} if (p & p-> adjvex = j) // locate the arc <v, w> {if (p = (* G ). vertices [I]. firstarc) // p refers to 1st arcs (* G ). vertices [I]. firstarc = p-> nextarc; // point to the next arc elseq-> nextarc = p-> nextarc; // point to the next arc if (* G ). kind % 2) // network free (p-> info); free (p); // release this node (* G ). arcnum --; // arc or edge number minus 1} if (* G ). kind> = 2) // undirected, delete symmetric arc <w, v> {p = (* G ). vertices [j]. firstarc; // p indicates the first arc of a margin while (p & p-> adjvex! = I) // p is not empty and the arc referred to is not the arc to be deleted <w, v >{// p points to the next arc q = p; p = p-> nextarc ;} if (p & p-> adjvex = I) // locate the arc <w, v> {if (p = (* G ). vertices [j]. firstarc) // p refers to 1st arcs (* G ). vertices [j]. firstarc = p-> nextarc; // point to the next arc elseq-> nextarc = p-> nextarc; // point to the next arc if (* G ). kind = 3) // undirected network free (p-> info); free (p); // release this node} return 1 ;} // recursively traverse the graph G Based on the v vertex. Void DFS (ALGraph G, int v) {int w; VertexType v1, w1; strcpy (v1, * GetVex (G, v); visited [v] = 1; // set the access flag to 1 (accessed) VisitFunc (G. vertices [v]. data); // access the v vertex for (w = FirstAdjVex (G, v1); w> = 0; w = NextAdjVex (G, v1, strcpy (w1, * GetVex (G, w) if (! Visited [w]) DFS (G, w); // recursively call DFS for the unaccessed neighbor w of v} // performs depth-first traversal on Graph G. Void DFSTraverse (ALGraph G, void (* Visit) (char *) {int v; // use the global variable VisitFunc so that DFS does not have to set the function pointer parameter VisitFunc = Visit; for (v = 0; v <G. vexnum; v ++) visited [v] = 0; // access flag array initialization for (v = 0; v <G. vexnum; v ++) if (! Visited [v]) DFS (G, v); // call DFS printf ("\ n") for unaccessed vertices;} // construct an empty queue Q. Int InitQueue (LinkQueue * Q) {(* Q ). front = (* Q ). rear = (QueuePtr) malloc (sizeof (QNode); // dynamically allocate a space if (! (* Q ). front) exit (0); (* Q ). front-> next = NULL; // The head pointer of the queue points to NULL and has no data fields. This constitutes an empty queue return 1 ;} // Insert a new team-end element whose Element e is Q. Int EnQueue (LinkQueue * Q, QElemType e) {QueuePtr p = (QueuePtr) malloc (sizeof (QNode); if (! P) // storage allocation failure exit (0); // generate a queue element p-> data = e; p-> next = NULL; // connect the new queue element to the backend (* Q ). rear-> next = p; (* Q ). rear = p; return 1 ;}// if the queue is not empty, delete the queue Header element of Q, use e to return its value, and return 1; otherwise, return 0. Int DeQueue (LinkQueue * Q, QElemType * e) {QueuePtr p; if (* Q ). front = (* Q ). rear) return 0; p = (* Q ). front-> next; // The Header element * e = p-> data; (* Q ). front-> next = p-> next; if (* Q ). rear = p) (* Q ). rear = (* Q ). front; free (p); return 1;} // If Q is an empty queue, 1 is returned; otherwise, 0 is returned. Int QueueEmpty (LinkQueue Q) {if (Q. front = Q. rear) return 1; elsereturn 0;} // traverse graph G by extensiveness first. Use the auxiliary queue Q and access flag array visited. Void BFSTraverse (ALGraph G, void (* Visit) (char *) {int v, u, w; VertexType u1, w1; LinkQueue Q; for (v = 0; v <G. vexnum; ++ v) visited [v] = 0; // sets the initial value of InitQueue (& Q); // sets the null auxiliary queue Q for (v = 0; v <G. vexnum; v ++) // if it is a connected graph, only v = 0 will traverse the entire graph if (! Visited [v]) // v has not been accessed {visited [v] = 1; Visit (G. vertices [v]. data); EnQueue (& Q, v); // v enters the queue while (! QueueEmpty (Q) // The queue is not empty {DeQueue (& Q, & u); // The team Header element is set to u strcpy (u1, * GetVex (G, u); for (w = FirstAdjVex (G, u1); w> = 0; w = NextAdjVex (G, u1, strcpy (w1, * GetVex (G, w) if (! Visited [w]) // w is the unaccessed adjacent vertex of u {visited [w] = 1; Visit (G. vertices [w]. data); EnQueue (& Q, w); // w join }}printf ("\ n") ;}// output graph's adjacent Table G. Void Display (ALGraph G) {int I; ArcNode * p; switch (G. kind) {case DG: printf ("Directed Graph \ n"); break; case DN: printf ("Directed Graph \ n"); break; case AG: printf ("undirected graph \ n"); break; case AN: printf ("undirected network \ n");} printf ("% d vertices: \ n", G. vexnum); for (I = 0; I <G. vexnum; ++ I) printf ("% s", G. vertices [I]. data); printf ("\ n % d arc (edge): \ n", G. arcnum); for (I = 0; I <G. vexnum; I ++) {p = G. vertices [I]. firstarc; while (p) {if (G. kind <= 1) // directed to {printf ("% s → % s", G. vertices [I]. data, G. vertices [p-> adjvex]. data); if (G. kind = DN) // network printf (": % d", * (p-> info);} else // undirected (avoid outputting twice) {if (I <p-> adjvex) {printf ("% s-% s", G. vertices [I]. data, G. vertices [p-> adjvex]. data); if (G. kind = AN) // network printf (": % d", * (p-> info) ;}} p = p-> nextarc ;} printf ("\ n") ;}} void print (char * I) {printf ("% s", I) ;}int main () {int I, j, k, n; ALGraph g; VertexType v1, v2; printf ("select directed graph \ n"); CreateGraph (& g); Display (g ); printf ("delete an edge or arc. Enter the arc tail arc header of the edge or arc to be deleted: \ n"); scanf ("% s", v1, v2); DeleteArc (& g, v1, v2); Display (g); printf ("to modify the vertex value, enter the original value :"); scanf ("% s", v1, v2); PutVex (& g, v1, v2); Display (g); printf ("Insert a new vertex, enter the vertex value: "); scanf (" % s ", v1); InsertVex (& g, v1); Display (g ); printf ("insert an arc or edge related to the new vertex. Enter the number of arcs or edges:"); scanf ("% d", & n); for (k = 0; k <n; k ++) {printf ("enter another vertex value:"); scanf ("% s", v2); printf ("For Directed Graphs, enter the direction of another vertex (0: arc header 1: arc tail): "); scanf (" % d ", & j); if (j) insertArc (& g, v2, v1); elseInsertArc (& g, v1, v2);} Display (g); printf ("delete vertices and related arcs or edges, enter the vertex value: "); scanf (" % s ", v1); DeleteVex (& g, v1); Display (g ); printf ("deep-first search results: \ n"); DFSTraverse (g, print); printf ("Results of breadth-first search: \ n"); BFSTraverse (g, print); DestroyGraph (& g); system ("pause"); return 0 ;}


Effect:



Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.