summaryrefslogtreecommitdiff
path: root/c/dataStructure/408/graph
diff options
context:
space:
mode:
authorgarhve <git@garhve.com>2022-12-05 19:43:39 +0800
committergarhve <git@garhve.com>2022-12-05 19:43:39 +0800
commitc6bc541ab58363d783e60a007e80e9bf9e231fda (patch)
treea59c7ed0d05225c5876f3e5e919d4f6ed0c447ff /c/dataStructure/408/graph
initialize
Diffstat (limited to 'c/dataStructure/408/graph')
-rwxr-xr-xc/dataStructure/408/graph/Makefile18
-rwxr-xr-xc/dataStructure/408/graph/dgraph.c164
-rwxr-xr-xc/dataStructure/408/graph/graph.h45
-rwxr-xr-xc/dataStructure/408/graph/main.c17
-rwxr-xr-xc/dataStructure/408/graph/queue/qtest.c21
-rwxr-xr-xc/dataStructure/408/graph/queue/queue.c78
-rwxr-xr-xc/dataStructure/408/graph/queue/queue.h26
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