diff options
author | garhve <git@garhve.com> | 2022-12-05 19:43:39 +0800 |
---|---|---|
committer | garhve <git@garhve.com> | 2022-12-05 19:43:39 +0800 |
commit | c6bc541ab58363d783e60a007e80e9bf9e231fda (patch) | |
tree | a59c7ed0d05225c5876f3e5e919d4f6ed0c447ff /c/dataStructure/408/graph |
initialize
Diffstat (limited to 'c/dataStructure/408/graph')
-rwxr-xr-x | c/dataStructure/408/graph/Makefile | 18 | ||||
-rwxr-xr-x | c/dataStructure/408/graph/dgraph.c | 164 | ||||
-rwxr-xr-x | c/dataStructure/408/graph/graph.h | 45 | ||||
-rwxr-xr-x | c/dataStructure/408/graph/main.c | 17 | ||||
-rwxr-xr-x | c/dataStructure/408/graph/queue/qtest.c | 21 | ||||
-rwxr-xr-x | c/dataStructure/408/graph/queue/queue.c | 78 | ||||
-rwxr-xr-x | c/dataStructure/408/graph/queue/queue.h | 26 |
7 files changed, 369 insertions, 0 deletions
diff --git a/c/dataStructure/408/graph/Makefile b/c/dataStructure/408/graph/Makefile new file mode 100755 index 0000000..d3565e8 --- /dev/null +++ b/c/dataStructure/408/graph/Makefile @@ -0,0 +1,18 @@ +CC = gcc +FLGS = -Wall -Werror -g +SRCS = *.c queue/queue.c +OPT = graph + +all: link run clean + +link: + $(CC) $(SRCS) $(FLGS) -o $(OPT) + +run: + ./$(OPT) + +gdb: link + gdb ./$(OPT) + +clean: + rm $(OPT) diff --git a/c/dataStructure/408/graph/dgraph.c b/c/dataStructure/408/graph/dgraph.c new file mode 100755 index 0000000..499fc0d --- /dev/null +++ b/c/dataStructure/408/graph/dgraph.c @@ -0,0 +1,164 @@ +#include "graph.h" + +/* Thdse functions can use for both direct or undirect graph, + * only be affected by argument 'directed' we give + */ + +void retreat(char * str) +{ + fprintf(stderr,"%s\n",str); + exit(EXIT_FAILURE); +} + +void initializeGraph(graph * g, bool directed) +{ + int i; /* counter */ + + g->nvertices = 0; + g->nedges = 0; + g->directed = directed; + + for (i = 1; i <= MAXV; i++) + g->degree[i] = 0; + + for (i = 1; i <= MAXV; i++) + g->edges[i] = NULL; +} + +/* x, y is a pair of vertices */ +void insertEdge(graph * g, int x, int y, bool directed) +{ + edgeNode * p; /* temporary pointer */ + + p = (edgeNode *) malloc (sizeof(edgeNode)); + if (!p) + retreat("Error allocate memory p"); + + p->weight = 0; + p->y = y; + + p->next = g->edges[x]; /* insert at head */ + g->edges[x] = p; + + g->degree[x]++; + + if (!directed) + insertEdge(g,y,x,true); /* add another one for undirected */ + else + g->nedges++; +} + +void readGraph(graph * g, bool directed) +{ + int i; /* counter */ + int m; /* number of edges */ + int x, y; /* vertices in edge (x, y) / <x, y> */ + + printf("Enter number of vertices and edges: "); + scanf ("%d%d", &(g->nvertices), &m); /* read number of vertices and edges */ + + printf("Enter two vertices consist one edge: "); + for (i = 1; i <= m; i++) + { + scanf("%d %d", &x, &y); /* readindex and vertex */ + insertEdge(g,x,y,directed); /* this is the one to make a graph */ + } +} + +void printGraph(graph * g) +{ + int i; /* counter */ + edgeNode * p; /* temporary pointer */ + + for (i = 1; i <= g->nvertices; i++) + { + printf("%d: ",i); + p = g->edges[i]; + while (p) + { + printf(" %d", p->y); + p = p->next; + } + putchar('\n'); + } +} + +void purgeGraph(graph * g) +{ + int i; /* counter */ + edgeNode * p, * q; /* temporary pointer */ + + for (i = 1; i < g->nvertices; i++) + { + p = g->edges[i]; + while (p) + { + q = p; + p = p->next; + free(q); + } + } +} + +void initializeSearch(graph * g) +{ + int i; + +// time = 0; + + for (i = 0; i <= g->nvertices; i++) + { + g->processed[i] = false; + g->discovered[i] = false; + g->parent[i] = -1; + } +} + +void processVertexEarly(int v) +{ + printf("processed vertex %d\n",v); +} +void processVertexLate(int v) +{ +} +void processEdge(int v, int y) +{ + printf("Process edge (%d,%d)\n",v,y); +} + +void bfs(graph * g, int start) +{ + queue q; /* queue of vertices to visit */ + int v; /* current vertex */ + int y; /* successor vertex */ + edgeNode * p; /* temporary pointer */ + + initializeSearch(g); + + initQueue(&q); + enQueue(&q,start); + g->discovered[start] = true; + + while (!emptyQueue(&q)) + { + v = deQueue(&q); + processVertexEarly(v); + g->processed[v] = true; + p = g->edges[v]; + + while (p) + { + y = p->y; + if (!g->processed[y] || g->directed) + processEdge(v,y); + if (!g->discovered[y]) + { + enQueue(&q,y); + g->discovered[y] = true; + g->parent[y] = v; + } + p = p->next; + } + processVertexLate(v); + } +} diff --git a/c/dataStructure/408/graph/graph.h b/c/dataStructure/408/graph/graph.h new file mode 100755 index 0000000..98b18bb --- /dev/null +++ b/c/dataStructure/408/graph/graph.h @@ -0,0 +1,45 @@ +#ifndef _GRAPH_H +#define _GRAPH_H + +/* + * We can use this header for both + * directed graph or undirected graph + * by toggle boolean flag 'directed' + * in graph structure. + */ + +#include<stdio.h> +#include<stdbool.h> +#include<stdlib.h> +#include "queue/queue.h" + +#define MAXV 5 /* maximum number of vertices */ + +typedef struct edgenode { + int y; /* adjacency info */ + int weight; /* edge weight if any */ + struct edgenode * next; /* next edge in list */ +} edgeNode; + +/* graph nodes start by 1 */ +typedef struct { + edgeNode * edges[MAXV + 1]; /* adjacency info */ + int degree[MAXV + 1]; /* outdegree of each vertex */ + int nvertices; /* number of vertices in graph */ + int nedges; /* number of edges in graph */ + bool directed; /* is the graph directed? */ + bool discovered[MAXV + 1]; + bool processed[MAXV + 1]; + int parent[MAXV + 1]; +} graph; + +void retreat (char * str); +void initializeGraph(graph * g, bool directed); +void readGraph (graph * g, bool directed); +void insertEdge (graph * g, int x, int y, bool directed); +void printGraph (graph * g); +void purgeGraph (graph * g); +void initializeSearch(graph * g); +void bfs(graph * g, int start); + +#endif diff --git a/c/dataStructure/408/graph/main.c b/c/dataStructure/408/graph/main.c new file mode 100755 index 0000000..6219969 --- /dev/null +++ b/c/dataStructure/408/graph/main.c @@ -0,0 +1,17 @@ +#include "graph.h" + +int main(void) +{ + graph gh; + bool directed = true; + initializeGraph(&gh,directed); + + readGraph(&gh,directed); + + printGraph(&gh); + bfs(&gh, 1); + + purgeGraph(&gh); + + return 0; +} diff --git a/c/dataStructure/408/graph/queue/qtest.c b/c/dataStructure/408/graph/queue/qtest.c new file mode 100755 index 0000000..61e01f2 --- /dev/null +++ b/c/dataStructure/408/graph/queue/qtest.c @@ -0,0 +1,21 @@ +#include "queue.h" + +int main(void) +{ + queue q; + + initQueue(&q); + enQueue(&q,10); + enQueue(&q,12); + printQueue(&q); + printf("deQueue1: %d\n",deQueue(&q)); + printf("deQueue2: %d\n",deQueue(&q)); + enQueue(&q,14); + printHead(&q); + printQueue(&q); + purgeQueue(&q); + if(emptyQueue(&q)) + puts("Empty Queue"); + + return 0; +} diff --git a/c/dataStructure/408/graph/queue/queue.c b/c/dataStructure/408/graph/queue/queue.c new file mode 100755 index 0000000..673c595 --- /dev/null +++ b/c/dataStructure/408/graph/queue/queue.c @@ -0,0 +1,78 @@ +#include "queue.h" + +void initQueue(Queue q) +{ + q->qhead = NULL; + q->qtail = NULL; +} + +void enQueue(Queue q, int y) +{ + elem * tmp = (elem*)malloc(sizeof(elem)); + + if (!tmp) + retreat("fail to enQueue"); + tmp->y = y; + tmp->next = NULL; + + if (!q->qtail) + { + q->qtail = tmp; + q->qhead = tmp; + } + else + { + q->qtail->next = tmp; + q->qtail = tmp; + } +} + +int deQueue(Queue q) +{ + bool flag = false; + if (!q->qhead) + retreat("Empty queue"); + if (q->qhead == q->qtail) + flag = true; + elem * tmp = q->qhead; + int p = tmp->y; + q->qhead = tmp->next; + free(tmp); + if (flag) + q->qtail = q->qhead; + return p; +} + +bool emptyQueue(Queue q) +{ + if (q->qhead) + return false; + return true; +} + +void purgeQueue(Queue q) +{ + elem * tmp; + while (q->qhead) + { + tmp = q->qhead; + q->qhead = tmp->next; + free(tmp); + } +} + +void printHead(Queue q) +{ + printf("Queue head is %d\n", q->qhead->y); +} + +void printQueue(Queue q) +{ + elem * tmp = q->qhead; + while (tmp) + { + printf("%d ",tmp->y); + tmp = tmp->next; + } + printf("\n"); +} diff --git a/c/dataStructure/408/graph/queue/queue.h b/c/dataStructure/408/graph/queue/queue.h new file mode 100755 index 0000000..145e598 --- /dev/null +++ b/c/dataStructure/408/graph/queue/queue.h @@ -0,0 +1,26 @@ +#ifndef _QUEUE_H +#define _QUEUE_H + +#include "../graph.h" + +typedef struct elem { + int y; + struct elem * next; +} elem; + +typedef struct queue { + elem * qhead; + elem * qtail; +} queue; + +typedef queue * Queue; + +void initQueue(Queue q); +void enQueue(Queue q, int y); +int deQueue(Queue q); +void purgeQueue(Queue q); +bool emptyQueue(Queue q); +void printHead(Queue q); +void printQueue(Queue q); + +#endif |