Skip to content

Commit 9252a3f

Browse files
authored
Graphs (#21)
* Graph enabled * Add/Del Vertex * Add/Del Edge for asymmetric and Symmetric edges * BFS * DFS for Graph Added TODO: Optimize for unvisited neighbors * - DFS optimized - Connected Components of graph implemented routine - Topologically sort/order DAGs enabled * Modified BFS and DFS to run on all connectected components of the graph * Modified DAG Topo order to get the Longest Path as well * Enabled Weighted Graph * Heap update node added * Dijkstra's Algorithm for shortest path - Implemented Dijkstra's Algorithm using heap - Generic heap implemented to store edge weight - Code clean up and cosmetics * Shortest Path Faster Algorithm - an improvement over Bellman Ford algorithm * Prim's Alogrithm for Minimum Spanning tree * Added new data Structure Disjoint sets (aka Union-Find aka Merge-Find data structures)
1 parent d33c3ef commit 9252a3f

19 files changed

Lines changed: 2017 additions & 19 deletions

File tree

Defs.make

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ STACK=true
2323
QUEUE=true
2424
HEAP=true
2525
TREE=true
26+
GRAPH=true
27+
DISJOINT_SET=true
2628

2729
#data struct define
2830
DS_FLAGS = -DLINK_LIST=$(LINK_LIST) -DSTACK=$(STACK) \
@@ -39,4 +41,6 @@ DS_FLAGS = -DLINK_LIST=$(LINK_LIST) -DSTACK=$(STACK) \
3941
@echo "QUEUES= $(QUEUE)"
4042
@echo "HEAPS= $(HEAP)"
4143
@echo "TREES= $(TREE)"
44+
@echo "GRAPHS= $(GRAPH)"
45+
@echo "DISJOINT_SET= $(DISJOINT_SET)"
4246

common/inc/common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,5 @@ typedef struct data_params {
3434
} t_dparams;
3535

3636
void init_data_params(t_dparams*, e_data_types);
37-
37+
void dummy_free(void *mem_addr, char *file, int line);
3838

common/inc/generic_def.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@
103103
return tmp;\
104104
}
105105

106+
/// Template function for getting element at a given index of an array for default data types
107+
#define GET_IDX_CPY(T, NAME) t_gen NAME(t_gen x, int idx1)\
108+
{ \
109+
T *arr = ((T*)(x));\
110+
t_gen tmp = get_mem(1, sizeof(T));\
111+
*(T*)tmp = arr[idx1] ;\
112+
return tmp;\
113+
}
114+
106115
/// Below routines defined as reference for basic datatypes
107116
e_cmpr compare_char(t_gen,t_gen);
108117
e_cmpr compare_int(t_gen,t_gen);
@@ -143,3 +152,12 @@ void copy_idx_float(t_gen,int,t_gen);
143152
t_gen get_idx_char(t_gen,int);
144153
t_gen get_idx_int(t_gen,int);
145154
t_gen get_idx_float(t_gen,int);
155+
156+
t_gen get_idx_char_cpy(t_gen,int);
157+
t_gen get_idx_int_cpy(t_gen,int);
158+
t_gen get_idx_float_cpy(t_gen,int);
159+
160+
e_cmpr gen_cmpr_idx(t_gen x, int idx1, int idx2);
161+
void gen_swp_idx(t_gen x, int idx1, int idx2);
162+
void gen_cpy_idx(t_gen x, int idx1, t_gen data);
163+
t_gen gen_get_idx(t_gen x, int idx1);

common/inc/os.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <pthread.h>
1616
#include <signal.h>
1717
#include <sys/time.h>
18+
#include <limits.h>
1819

1920
/// Custom malloc if not defined use calloc and free
2021
#ifndef CUSTOM_MALLOC

common/inc/typedefs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ typedef void* t_gen; ///< Generic data pointer
4545
/// Generic data pointer definitions that are common to most data structure operations
4646
typedef t_gen (*f_gen)(t_gen); ///< fn ptr that takes one gen ptr and return gen ptr
4747
typedef t_gen (*f_gen2)(t_gen, t_gen); ///< fn ptr that takes two gen ptr and return gen ptr
48+
typedef t_gen (*f_gen3)(t_gen, t_gen, t_gen); ///< fn ptr that takes three gen ptr and return gen ptr
4849
typedef void (*f_vgen)(t_gen); ///< fn ptr that takes one gen ptr and return nothing
4950
typedef void (*f_vgen2)(t_gen, t_gen); ///< fn ptr that takes two gen ptr and return nothing
5051
typedef t_gen (*f_genidx)(t_gen, int); ///< fn ptr that takes one gen ptr, idx and return gen ptr

common/src/common.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
#include "common.h"
66

7+
78
/*! @brief
89
* Called to initalize data params for default data types
910
* Else for custom data types the data params structure is to be defined by user
@@ -65,4 +66,13 @@ void init_data_params(t_dparams *prms, e_data_types data_type)
6566
}
6667
}
6768

69+
/*! @brief
70+
* Dummy free function
71+
* Else for custom data types the data params structure is to be defined by user
72+
* @param mem_addr - mem to be free'd
73+
* @return - NA
74+
*/
75+
void dummy_free(void *mem_addr, char *file, int line)
76+
{
6877

78+
}

common/src/generic_def.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,37 @@ void print_str(t_gen str)
6565
printf("%s", (char*)str);
6666
}
6767

68+
t_gen gen_get_idx(t_gen x, int idx1)
69+
{
70+
t_gen *arr = ((t_gen*)(x));
71+
return arr[idx1];
72+
}
73+
74+
void gen_cpy_idx(t_gen x, int idx1, t_gen data)
75+
{
76+
t_gen *arr = ((t_gen*)(x));
77+
arr[idx1] = data;
78+
}
79+
80+
void gen_swp_idx(t_gen x, int idx1, int idx2)
81+
{
82+
t_gen *arr = (t_gen*)(x);
83+
t_gen tmp = arr[idx1];
84+
arr[idx1] = arr[idx2];
85+
arr[idx2] = tmp;
86+
}
87+
88+
e_cmpr gen_cmpr_idx(t_gen x, int idx1, int idx2)
89+
{
90+
e_cmpr ret = eEQUAL;
91+
t_gen *arr = ((t_gen*)(x));
92+
t_gen tmp = (t_gen)(arr[idx1] -arr[idx2]);
93+
if (tmp < 0)
94+
ret = eLESS;
95+
else if (tmp > 0)
96+
ret = eGREAT;
97+
return ret;
98+
}
6899
CMPR_IDX(char,compare_idx_char)
69100
CMPR_IDX(int,compare_idx_int)
70101
CMPR_IDX(float,compare_idx_float)
@@ -81,3 +112,7 @@ GET_IDX(char, get_idx_char)
81112
GET_IDX(int, get_idx_int)
82113
GET_IDX(float, get_idx_float)
83114

115+
GET_IDX_CPY(char, get_idx_char_cpy)
116+
GET_IDX_CPY(int, get_idx_int_cpy)
117+
GET_IDX_CPY(float, get_idx_float_cpy)
118+

ds/Makefile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ stack_ARCHIVE=$(PROJ_PATH)/ds/stack/stack.o
44
queue_ARCHIVE=$(PROJ_PATH)/ds/queue/queue.o
55
heap_ARCHIVE=$(PROJ_PATH)/ds/heap/heap.o
66
tree_ARCHIVE=$(PROJ_PATH)/ds/tree/tree.o
7+
graph_ARCHIVE=$(PROJ_PATH)/ds/graph/graph.o
8+
disjoint_set_ARCHIVE=$(PROJ_PATH)/ds/disjoint_set/disjoint_set.o
79

810
ds_ARCHIVE=$(PROJ_PATH)/ds/bin/ds.a
911

@@ -34,6 +36,16 @@ INCLUDES += -I $(PROJ_PATH)/ds/tree/
3436
sub_ARCHIVE += $(tree_ARCHIVE)
3537
endif
3638

39+
ifeq ($(GRAPH), true)
40+
INCLUDES += -I $(PROJ_PATH)/ds/graph/
41+
sub_ARCHIVE += $(graph_ARCHIVE)
42+
endif
43+
44+
ifeq ($(DISJOINT_SET), true)
45+
INCLUDES += -I $(PROJ_PATH)/ds/disjoint_set/
46+
sub_ARCHIVE += $(disjoint_set_ARCHIVE)
47+
endif
48+
3749
all: $(ds_ARCHIVE)
3850

3951
$(ds_ARCHIVE): $(sub_ARCHIVE)
@@ -56,6 +68,12 @@ $(heap_ARCHIVE) :
5668
$(tree_ARCHIVE) :
5769
make -C tree/ all
5870

71+
$(graph_ARCHIVE) :
72+
make -C graph/ all
73+
74+
$(disjoint_set_ARCHIVE) :
75+
make -C disjoint_set/ all
76+
5977
clean:
6078
rm -rf $(ds_ARCHIVE) $(sub_ARCHIVE)
6179

ds/disjoint_set/Makefile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
disjoint_set_SRC=disjoint_set.c
2+
disjoint_set_OBJ=disjoint_set.o
3+
4+
OBJS=$(disjoint_set_OBJ)
5+
6+
all: $(OBJS)
7+
8+
$(disjoint_set_OBJ): $(disjoint_set_SRC)
9+
$(CC) $(INCLUDES) -c $^ -o $@ $(CFLAGS)
10+
11+
12+
.PHONY: clean
13+
14+
clean:
15+
rm -rf $(disjoint_set_ARCHIVE) $(OBJS)

ds/disjoint_set/disjoint_set.c

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/*! @file disjoint_set.c
2+
@brief
3+
Contains definitions of routines supported by disjoint_set
4+
*/
5+
#include "disjoint_set.h"
6+
7+
void destroy_disjoint_set(t_gen d);
8+
void disjoint_set_make (t_gen d);
9+
int disjoint_set_find(t_gen d, int x);
10+
int disjoint_set_merge (t_gen d, int x, int y);
11+
void disjoint_set_print (t_gen d);
12+
13+
14+
/*! @brief
15+
* Create an instance of disjoint set data struct
16+
* @param name - Name of disjoint set instance
17+
* @param size - size of the disjoin set
18+
* @return - Pointer to instance of disjoint set
19+
* */
20+
t_gen create_disjoint_set(char *name, int size)
21+
{
22+
t_disjset *set = get_mem(1, sizeof(t_disjset));
23+
24+
set->name = name;
25+
set->size = size;
26+
set->subset = get_mem(size, sizeof(t_dsetnode));
27+
28+
set->make = disjoint_set_make;
29+
set->find = disjoint_set_find;
30+
set->merge = disjoint_set_merge;
31+
32+
set->print = disjoint_set_print;
33+
set->destroy = destroy_disjoint_set;
34+
35+
return set;
36+
}
37+
38+
/*! @brief
39+
* Destroy the instance of disjoint set data struct
40+
* @param d - Pointer to instance of disjoint set
41+
* @return - NA
42+
* */
43+
void destroy_disjoint_set(t_gen d)
44+
{
45+
t_disjset *set = (t_disjset*)d;
46+
47+
free_mem(set->subset);
48+
free_mem(set);
49+
}
50+
51+
/*! @brief
52+
* The MakeSet operation adds a new element
53+
* @param d - Pointer to instance of disjoint set
54+
* @return - NA
55+
* */
56+
void disjoint_set_make (t_gen d)
57+
{
58+
t_disjset *set = (t_disjset*)d;
59+
60+
for(int i = 0; i < set->size; i++) {
61+
set->subset[i].size = 1;
62+
set->subset[i].parent = i;
63+
}
64+
}
65+
66+
/*! @brief
67+
* Find the set the node belongs to
68+
* the method defined follows path halving
69+
* @see https://en.wikipedia.org/wiki/Disjoint-set_data_structure
70+
* @param d - Pointer to instance of disjoint set
71+
* @param x - idx of node
72+
* @return - return the root element of the disjoint set
73+
* */
74+
int disjoint_set_find(t_gen d, int x)
75+
{
76+
t_disjset *set = (t_disjset*)d;
77+
int parent = set->subset[x].parent;
78+
while (parent != x) {
79+
parent = set->subset[x].parent;
80+
set->subset[x].parent = set->subset[parent].parent;
81+
x = set->subset[x].parent;
82+
}
83+
84+
return x;
85+
}
86+
87+
/*! @brief
88+
* Merge the given two subsets
89+
* @see https://en.wikipedia.org/wiki/Disjoint-set_data_structure
90+
* @param d - Pointer to instance of disjoint set
91+
* @param x - idx of first node
92+
* @param y - idx of second node
93+
* @return - if nodes already merged return -1 else 0 on merge
94+
* */
95+
int disjoint_set_merge (t_gen d, int x, int y)
96+
{
97+
t_disjset *set = (t_disjset*)d;
98+
99+
x = set->find(set, x);
100+
y = set->find(set, y);
101+
102+
if (x == y) {
103+
return -1;
104+
}
105+
106+
if (set->subset[x].size < set->subset[y].size) {
107+
set->subset[x].parent = y;
108+
set->subset[x].size += set->subset[y].size;
109+
}
110+
else {
111+
set->subset[y].parent = x;
112+
set->subset[y].size += set->subset[x].size;
113+
}
114+
115+
return 0;
116+
}
117+
118+
/*! @brief
119+
* Print the elem of the disjoint set
120+
* @param d - Pointer to instance of link list
121+
* @return - NA
122+
* */
123+
void disjoint_set_print (t_gen d)
124+
{
125+
t_disjset *set = (t_disjset*)d;
126+
127+
128+
for(int i = 0; i < set->size; i++) {
129+
printf("[%d: %d %d] ",i, set->subset[i].parent,
130+
set->subset[i].size);
131+
}
132+
printf("\n");
133+
}

0 commit comments

Comments
 (0)