Skip to content

Added Graph and Greedy Algos #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions Graphs/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
CC=gcc
CFLAGS=-Wall -Werror -std=c99
all: BFS Bellman-Ford DFS Dijkstra Floyd-Warshall bfsQueue dfsRecursive euler hamiltonian strongly_connected_components topologicalSort transitiveClosure


BFS: BFS.c
$(CC) -o BFS BFS.c
Bellman-Ford: Bellman-Ford.c
$(CC) -o Bellman-Ford Bellman-Ford.c
DFS: DFS.c
$(CC) -o DFS DFS.c
Dijkstra: Dijkstra.c
$(CC) -o Dijkstra Dijkstra.c
Floyd-Warshall: Floyd-Warshall.c
$(CC) -o Floyd-Warshall Floyd-Warshall.c
Graph.o: Graph.c Graph.h
$(CC) $(CFLAGS) -c Graph.c
bfsQueue: Graph.o queue.o bfsQueue.o
$(CC) Graph.o queue.o bfsQueue.o -o bfsQueue
bfsQueue.o: bfsQueue.c
$(CC) $(CFLAGS) -c bfsQueue.c
dfsRecursive: Graph.o queue.o dfsRecursive.o
$(CC) Graph.o queue.o dfsRecursive.o -o dfsRecursive
dfsRecursive.o: dfsRecursive.c
$(CC) -c dfsRecursive.c
euler: Graph.o euler.o
$(CC) Graph.o euler.o -o euler
euler.o: euler.c
$(CC) $(CFLAGS) -c euler.c
hamiltonian: Graph.o hamiltonian.o
$(CC) Graph.o hamiltonian.o -o hamiltonian
hamiltonian.o: hamiltonian.c
$(CC) $(CFLAGS) -c hamiltonian.c
queue.o: queue.c queue.h
$(CC) $(CFLAGS) -c queue.c
strongly_connected_components: strongly_connected_components.c
$(CC) -o strongly_connected_components strongly_connected_components.c
topologicalSort: topologicalSort.c
$(CC) -o topologicalSort topologicalSort.c
transitiveClosure: transitiveClosure.c
$(CC) -o transitiveClosure transitiveClosure.c

By Vishal Kumar
Github: vishaaal
140 changes: 140 additions & 0 deletions Graphs/bellman_ford.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Structure for storing edge
struct Edge
{
int src, dst, weight;
};

// Structure for storing a graph
struct Graph
{
int vertexNum;
int edgeNum;
struct Edge *edges;
};

// Constructs a graph with V vertices and E edges
void createGraph(struct Graph *G, int V, int E)
{
G->vertexNum = V;
G->edgeNum = E;
G->edges = (struct Edge *)malloc(E * sizeof(struct Edge));
}

// Adds the given edge to the graph
void addEdge(struct Graph *G, int src, int dst, int weight)
{
static int ind;
struct Edge newEdge;
newEdge.src = src;
newEdge.dst = dst;
newEdge.weight = weight;
G->edges[ind++] = newEdge;
}

// Utility function to find minimum distance vertex in mdist
int minDistance(int mdist[], int vset[], int V)
{
int minVal = INT_MAX, minInd;
for (int i = 0; i < V; i++)
if (vset[i] == 0 && mdist[i] < minVal)
{
minVal = mdist[i];
minInd = i;
}

return minInd;
}

// Utility function to print distances
void print(int dist[], int V)
{
printf("\nVertex Distance\n");
for (int i = 0; i < V; i++)
{
if (dist[i] != INT_MAX)
printf("%d\t%d\n", i, dist[i]);
else
printf("%d\tINF", i);
}
}

// The main function that finds the shortest path from given source
// to all other vertices using Bellman-Ford.It also detects negative
// weight cycle
void BellmanFord(struct Graph *graph, int src)
{
int V = graph->vertexNum;
int E = graph->edgeNum;
int dist[V];

// Initialize distances array as INF for all except source
// Intialize source as zero
for (int i = 0; i < V; i++) dist[i] = INT_MAX;
dist[src] = 0;

// Calculate shortest path distance from source to all edges
// A path can contain maximum (|V|-1) edges
for (int i = 0; i <= V - 1; i++)
for (int j = 0; j < E; j++)
{
int u = graph->edges[j].src;
int v = graph->edges[j].dst;
int w = graph->edges[j].weight;

if (dist[u] != INT_MAX && dist[u] + w < dist[v])
dist[v] = dist[u] + w;
}

// Iterate inner loop once more to check for negative cycle
for (int j = 0; j < E; j++)
{
int u = graph->edges[j].src;
int v = graph->edges[j].dst;
int w = graph->edges[j].weight;

if (dist[u] != INT_MAX && dist[u] + w < dist[v])
{
printf(
"Graph contains negative weight cycle. Hence, shortest "
"distance not guaranteed.");
return;
}
}

print(dist, V);

return;
}

// Driver Function
int main()
{
int V, E, gsrc;
int src, dst, weight;
struct Graph G;
printf("Enter number of vertices: ");
scanf("%d", &V);
printf("Enter number of edges: ");
scanf("%d", &E);
createGraph(&G, V, E);
for (int i = 0; i < E; i++)
{
printf("\nEdge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
printf("Enter weight: ");
scanf("%d", &weight);
addEdge(&G, src, dst, weight);
}
printf("\nEnter source:");
scanf("%d", &gsrc);
BellmanFord(&G, gsrc);

return 0;
}
195 changes: 195 additions & 0 deletions Graphs/bfs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#include <stdio.h>
#include <stdlib.h>
#define SIZE 40
// Assume max size of graph is 40 nodes
struct queue
{
int items[SIZE];
int front;
int rear;
};

// Some declarations
struct queue *createQueue();
void enqueue(struct queue *q, int);
int dequeue(struct queue *q);
void display(struct queue *q);
int isEmpty(struct queue *q);
int pollQueue(struct queue *q);

// Structure to create a graph node
struct node
{
int vertex;
struct node *next;
};

struct node *createNode(int);

// Graph data structure
struct Graph
{
int numVertices;
struct node **adjLists;
int *visited;
};
struct Graph *createGraph(int vertices);
void addEdge(struct Graph *graph, int src, int dest);
void printGraph(struct Graph *graph);
void bfs(struct Graph *graph, int startVertex);

int main()
{
int vertices, edges, source, i, src, dst;
printf("Enter the number of vertices\n");
scanf("%d", &vertices);
struct Graph *graph = createGraph(vertices);
printf("Enter the number of edges\n");
scanf("%d", &edges);
for (i = 0; i < edges; i++)
{
printf("Edge %d \nEnter source: ", i + 1);
scanf("%d", &src);
printf("Enter destination: ");
scanf("%d", &dst);
addEdge(graph, src, dst);
}
printf("Enter source of bfs\n");
scanf("%d", &source);
bfs(graph, source);

// Uncomment below part to get a ready-made example
/*struct Graph* graph = createGraph(6);
addEdge(graph, 0, 1);
addEdge(graph, 0, 2);
addEdge(graph, 1, 2);
addEdge(graph, 1, 4);
addEdge(graph, 1, 3);
addEdge(graph, 2, 4);
addEdge(graph, 3, 4);
bfs(graph,0);*/

return 0;
}
void bfs(struct Graph *graph, int startVertex)
{
struct queue *q = createQueue();

// Add to visited list and put in queue
graph->visited[startVertex] = 1;
enqueue(q, startVertex);
printf("Breadth first traversal from vertex %d is:\n", startVertex);

// Iterate while queue not empty
while (!isEmpty(q))
{
printf("%d ", pollQueue(q));
int currentVertex = dequeue(q);

struct node *temp = graph->adjLists[currentVertex];
// Add all unvisited neighbours of current vertex to queue to be printed
// next
while (temp)
{
int adjVertex = temp->vertex;
// Only add if neighbour is unvisited
if (graph->visited[adjVertex] == 0)
{
graph->visited[adjVertex] = 1;
enqueue(q, adjVertex);
}
temp = temp->next;
}
}
}
// Memory for a graph node
struct node *createNode(int v)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->vertex = v;
newNode->next = NULL;
return newNode;
}
// Allocates memory for graph data structure, in adjacency list format
struct Graph *createGraph(int vertices)
{
struct Graph *graph = malloc(sizeof(struct Graph));
graph->numVertices = vertices;

graph->adjLists = malloc(vertices * sizeof(struct node *));
graph->visited = malloc(vertices * sizeof(int));

int i;
for (i = 0; i < vertices; i++)
{
graph->adjLists[i] = NULL;
graph->visited[i] = 0;
}

return graph;
}
// Adds bidirectional edge to graph
void addEdge(struct Graph *graph, int src, int dest)
{
// Add edge from src to dest
struct node *newNode = createNode(dest);
newNode->next = graph->adjLists[src];
graph->adjLists[src] = newNode;

// Add edge from dest to src; comment it out for directed graph
newNode = createNode(src);
newNode->next = graph->adjLists[dest];
graph->adjLists[dest] = newNode;
}
// Allocates memory for our queue data structure
struct queue *createQueue()
{
struct queue *q = malloc(sizeof(struct queue));
q->front = -1;
q->rear = -1;
return q;
}
// Checks for empty queue
int isEmpty(struct queue *q)
{
if (q->rear == -1)
return 1;
else
return 0;
}
// Inserts item at start of queue
void enqueue(struct queue *q, int value)
{
if (q->rear == SIZE - 1)
printf("\nQueue is Full!!");
else
{
if (q->front == -1)
q->front = 0;
q->rear++;
q->items[q->rear] = value;
}
}
// Returns item at front of queue and removes it from queue
int dequeue(struct queue *q)
{
int item;
if (isEmpty(q))
{
printf("Queue is empty");
item = -1;
}
else
{
item = q->items[q->front];
q->front++;
if (q->front > q->rear)
{
q->front = q->rear = -1;
}
}
return item;
}

// Returns element at front of queue
int pollQueue(struct queue *q) { return q->items[q->front]; }
Loading