diff --git a/Makefile b/Makefile index 5082b847..d4765190 100644 --- a/Makefile +++ b/Makefile @@ -98,7 +98,7 @@ endif SRCS = $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) SRCS := $(filter-out src/utils/io_utility.c,$(SRCS)) OBJS = $(patsubst %.c,$(OBJ_DIR)/%.o,$(SRCS)) -HELP_OBJS = $(OBJ_DIR)/help/help.o $(OBJ_DIR)/help/help_data_structures.o $(OBJ_DIR)/help/help_sorting_searching.o $(OBJ_DIR)/help/help_graphs_trees.o $(OBJ_DIR)/help/help_advanced_topics.o $(OBJ_DIR)/help/help_expression_evaluation.o +HELP_OBJS = $(OBJ_DIR)/help/help.o $(OBJ_DIR)/help/help_data_structures.o $(OBJ_DIR)/help/help_sorting_searching.o $(OBJ_DIR)/help/help_graphs_trees.o $(OBJ_DIR)/help/help_advanced_topics.o $(OBJ_DIR)/help/help_expression_evaluation.o $(OBJ_DIR)/help/help_error_correction.o $(OBJ_DIR)/help/help_hashing.o TARGET = dsa diff --git a/src/advanced_graph_algorithms/advanced_graph_algorithms.h b/src/advanced_graph_algorithms/advanced_graph_algorithms.h index 0f7a47e3..4c4a4e28 100644 --- a/src/advanced_graph_algorithms/advanced_graph_algorithms.h +++ b/src/advanced_graph_algorithms/advanced_graph_algorithms.h @@ -10,12 +10,17 @@ int** find_scc_tarjan(Graph* graph, int* scc_count, int** scc_sizes); int** find_scc_kosaraju(Graph* graph, int* scc_count, int** scc_sizes); void free_scc_result(int** sccs, int* scc_sizes, int scc_count); void scc_demo(void); +void tarjan_scc_demo(void); +void kosaraju_scc_demo(void); // ------------------For Maximum Flow----------------------------------------- int ford_fulkerson(weightedGraph* graph, int source, int sink); int edmonds_karp(weightedGraph* graph, int source, int sink); int dinic(weightedGraph* graph, int source, int sink); void max_flow_demo(void); +void ford_fulkerson_demo(void); +void edmonds_karp_demo(void); +void dinic_demo(void); bool bipartite_color(Graph* graph, int* color); // ------------------For Bipartite Matching----------------------------------- @@ -26,6 +31,8 @@ int hopcroft_karp(Graph* graph, int** match_pairs, int* match_count); int find_eulerian_path(Graph* graph, int** path, int* path_len); void bipartite_matching_demo(void); +void dinic_bipartite_matching_demo(void); +void hopcroft_karp_demo(void); void eulerian_path_demo(void); void advanced_graph_algorithms_demo(void); diff --git a/src/advanced_graph_algorithms/bipartite_matching.c b/src/advanced_graph_algorithms/bipartite_matching.c index 3b31e407..c2b1d9e8 100644 --- a/src/advanced_graph_algorithms/bipartite_matching.c +++ b/src/advanced_graph_algorithms/bipartite_matching.c @@ -266,27 +266,26 @@ int max_bipartite_matching(Graph* graph, int** match_pairs, int* match_count) return count; } -void bipartite_matching_demo(void) +static Graph* get_bipartite_matching_graph(void) { int vertices, edges; Graph* graph = NULL; - printf("\nMaximum Bipartite Matching Demo\n"); int input_status = safe_input_int(&vertices, "Enter number of vertices (2-20): ", 2, 20); if (input_status == INPUT_EXIT_SIGNAL) - return; + return NULL; graph = create_graph(vertices); if (graph == NULL) { printf("\nError: Memory allocation failed for graph.\n"); - return; + return NULL; } int edge_status = safe_input_int(&edges, "Enter number of edges (1-100): ", 1, 100); if (edge_status == INPUT_EXIT_SIGNAL) { free_graph(graph); - return; + return NULL; } printf("Enter undirected edges (u v) with vertices from 0 to %d:\n", vertices - 1); @@ -296,15 +295,85 @@ void bipartite_matching_demo(void) if (safe_input_int(&u, "u: ", 0, vertices - 1) == INPUT_EXIT_SIGNAL) { free_graph(graph); - return; + return NULL; } if (safe_input_int(&v, "v: ", 0, vertices - 1) == INPUT_EXIT_SIGNAL) { free_graph(graph); - return; + return NULL; } add_edge_undirected(graph, u, v); } + return graph; +} + +void dinic_bipartite_matching_demo(void) +{ + Graph* graph = get_bipartite_matching_graph(); + if (graph == NULL) + return; + + printf("\nMaximum Bipartite Matching Demo (Dinic's Flow Network)\n"); + + int match_count_dinic = 0; + int* match_pairs_dinic = NULL; + int max_dinic = max_bipartite_matching(graph, &match_pairs_dinic, &match_count_dinic); + + printf("\n=== Bipartite Matching Results (Dinic's) ===\n"); + printf("Max Matching: %d\n", max_dinic); + if (match_count_dinic > 0) + { + printf("Matching Pairs: "); + for (int i = 0; i < match_count_dinic; i++) + { + printf("(%d - %d) ", match_pairs_dinic[2 * i], match_pairs_dinic[2 * i + 1]); + } + printf("\n"); + free(match_pairs_dinic); + } + + free_graph(graph); + printf("\nPress Enter to continue..."); + getchar(); +} + +void hopcroft_karp_demo(void) +{ + Graph* graph = get_bipartite_matching_graph(); + if (graph == NULL) + return; + + printf("\nMaximum Bipartite Matching Demo (Hopcroft-Karp)\n"); + + int match_count_hk = 0; + int* match_pairs_hk = NULL; + int max_hk = hopcroft_karp(graph, &match_pairs_hk, &match_count_hk); + + printf("\n=== Bipartite Matching Results (Hopcroft-Karp) ===\n"); + printf("Max Matching: %d\n", max_hk); + if (match_count_hk > 0) + { + printf("Matching Pairs: "); + for (int i = 0; i < match_count_hk; i++) + { + printf("(%d - %d) ", match_pairs_hk[2 * i], match_pairs_hk[2 * i + 1]); + } + printf("\n"); + free(match_pairs_hk); + } + + free_graph(graph); + printf("\nPress Enter to continue..."); + getchar(); +} + +void bipartite_matching_demo(void) +{ + Graph* graph = get_bipartite_matching_graph(); + if (graph == NULL) + return; + + printf("\nMaximum Bipartite Matching Demo\n"); int match_count_dinic = 0; int* match_pairs_dinic = NULL; diff --git a/src/advanced_graph_algorithms/ford_fulkerson_visualize.c b/src/advanced_graph_algorithms/ford_fulkerson_visualize.c index 622c4b3f..99cd3242 100644 --- a/src/advanced_graph_algorithms/ford_fulkerson_visualize.c +++ b/src/advanced_graph_algorithms/ford_fulkerson_visualize.c @@ -599,7 +599,7 @@ static void visualize_dinic(weightedGraph* graph, int source, int sink) free(parent); } -void max_flow_demo(void) +static weightedGraph* get_max_flow_demo_graph(int* out_graph_capacity) { int edges; int graph_capacity = 0; @@ -616,7 +616,7 @@ void max_flow_demo(void) if (method_status == INPUT_EXIT_SIGNAL) { printf("\nExiting Max Flow visualization demo.....\n"); - return; + return NULL; } if (method_status == 0) @@ -639,7 +639,7 @@ void max_flow_demo(void) { printf("\ninput ended unexpectedly\n"); clearerr(stdin); - return; + return NULL; } size_t len = strlen(path); @@ -649,7 +649,7 @@ void max_flow_demo(void) if (strcmp(path, "-1") == 0) { printf("\nExiting Max Flow visualization demo.....\n"); - return; + return NULL; } if (len == 0) @@ -681,7 +681,7 @@ void max_flow_demo(void) if (graph_capacity_status == INPUT_EXIT_SIGNAL) { printf("\nExiting Max Flow visualization demo.....\n"); - return; + return NULL; } if (graph_capacity_status == 0) @@ -693,7 +693,7 @@ void max_flow_demo(void) if (!graph) { printf("\nmalloc allocation failed\n"); - return; + return NULL; } break; @@ -710,7 +710,7 @@ void max_flow_demo(void) { printf("\nExiting Max Flow visualization demo\n"); free_weightedGraph(graph); - return; + return NULL; } if (edges_capacity_status == 0) @@ -741,7 +741,7 @@ void max_flow_demo(void) { printf("\nExiting Max Flow visualization demo\n"); free_weightedGraph(graph); - return; + return NULL; } if (src_status == 0) { @@ -754,7 +754,7 @@ void max_flow_demo(void) { printf("\nExiting Max Flow visualization demo\n"); free_weightedGraph(graph); - return; + return NULL; } if (dest_status == 0) { @@ -766,7 +766,7 @@ void max_flow_demo(void) { printf("\nExiting Max Flow visualization demo\n"); free_weightedGraph(graph); - return; + return NULL; } if (wt_status == 0) { @@ -777,14 +777,19 @@ void max_flow_demo(void) } } + *out_graph_capacity = graph_capacity; + return graph; +} + +static bool get_source_sink(int graph_capacity, int* out_source, int* out_sink) +{ int source, sink; while (1) { int src_status = safe_input_int(&source, "Enter source node: ", 0, graph_capacity - 1); if (src_status == INPUT_EXIT_SIGNAL) { - free_weightedGraph(graph); - return; + return false; } if (src_status == 0) continue; @@ -792,8 +797,7 @@ void max_flow_demo(void) int sink_status = safe_input_int(&sink, "Enter sink node: ", 0, graph_capacity - 1); if (sink_status == INPUT_EXIT_SIGNAL) { - free_weightedGraph(graph); - return; + return false; } if (sink_status == 0) continue; @@ -805,6 +809,69 @@ void max_flow_demo(void) } break; } + *out_source = source; + *out_sink = sink; + return true; +} + +void ford_fulkerson_demo(void) +{ + int graph_capacity; + weightedGraph* graph = get_max_flow_demo_graph(&graph_capacity); + if (graph == NULL) + return; + + int source, sink; + if (get_source_sink(graph_capacity, &source, &sink)) + { + visualize_ford_fulkerson(graph, source, sink); + } + free_weightedGraph(graph); +} + +void edmonds_karp_demo(void) +{ + int graph_capacity; + weightedGraph* graph = get_max_flow_demo_graph(&graph_capacity); + if (graph == NULL) + return; + + int source, sink; + if (get_source_sink(graph_capacity, &source, &sink)) + { + visualize_edmonds_karp(graph, source, sink); + } + free_weightedGraph(graph); +} + +void dinic_demo(void) +{ + int graph_capacity; + weightedGraph* graph = get_max_flow_demo_graph(&graph_capacity); + if (graph == NULL) + return; + + int source, sink; + if (get_source_sink(graph_capacity, &source, &sink)) + { + visualize_dinic(graph, source, sink); + } + free_weightedGraph(graph); +} + +void max_flow_demo(void) +{ + int graph_capacity; + weightedGraph* graph = get_max_flow_demo_graph(&graph_capacity); + if (graph == NULL) + return; + + int source, sink; + if (!get_source_sink(graph_capacity, &source, &sink)) + { + free_weightedGraph(graph); + return; + } int choice; while (1) diff --git a/src/advanced_graph_algorithms/scc_visualize.c b/src/advanced_graph_algorithms/scc_visualize.c index 31e86a0d..755d690b 100644 --- a/src/advanced_graph_algorithms/scc_visualize.c +++ b/src/advanced_graph_algorithms/scc_visualize.c @@ -392,7 +392,7 @@ static void visualize_kosaraju(Graph* graph) free_scc_result(sccs, sizes, count); } -void scc_demo(void) +static Graph* get_scc_demo_graph(void) { int edges; int graph_capacity; @@ -409,7 +409,7 @@ void scc_demo(void) if (method_status == INPUT_EXIT_SIGNAL) { printf("\nExiting SCC visualization demo.....\n"); - return; + return NULL; } if (method_status == 0) @@ -432,7 +432,7 @@ void scc_demo(void) { printf("\ninput ended unexpectedly\n"); clearerr(stdin); - return; + return NULL; } size_t len = strlen(path); @@ -442,7 +442,7 @@ void scc_demo(void) if (strcmp(path, "-1") == 0) { printf("\nExiting SCC visualization demo.....\n"); - return; + return NULL; } if (len == 0) @@ -474,7 +474,7 @@ void scc_demo(void) if (graph_capacity_status == INPUT_EXIT_SIGNAL) { printf("\nExiting SCC visualization demo.....\n"); - return; + return NULL; } if (graph_capacity_status == 0) @@ -486,7 +486,7 @@ void scc_demo(void) if (!graph) { printf("\nmalloc allocation failed\n"); - return; + return NULL; } break; @@ -503,7 +503,7 @@ void scc_demo(void) { printf("\nExiting SCC visualization demo\n"); free_graph(graph); - return; + return NULL; } if (edges_capacity_status == 0) @@ -531,7 +531,7 @@ void scc_demo(void) { printf("\nExiting SCC visualization demo\n"); free_graph(graph); - return; + return NULL; } if (src_status == 0) { @@ -544,7 +544,7 @@ void scc_demo(void) { printf("\nExiting SCC visualization demo\n"); free_graph(graph); - return; + return NULL; } if (dest_status == 0) { @@ -554,6 +554,36 @@ void scc_demo(void) add_edge_directed_unweighted(graph, src, dest); } } + return graph; +} + +void tarjan_scc_demo(void) +{ + Graph* graph = get_scc_demo_graph(); + if (graph != NULL) + { + visualize_tarjan(graph); + free_graph(graph); + } +} + +void kosaraju_scc_demo(void) +{ + Graph* graph = get_scc_demo_graph(); + if (graph != NULL) + { + visualize_kosaraju(graph); + free_graph(graph); + } +} + +void scc_demo(void) +{ + Graph* graph = get_scc_demo_graph(); + if (graph == NULL) + { + return; + } int choice; while (1) diff --git a/src/advanced_sorting_algorithms/radix_sort.c b/src/advanced_sorting_algorithms/radix_sort.c index f0153b06..a225f640 100644 --- a/src/advanced_sorting_algorithms/radix_sort.c +++ b/src/advanced_sorting_algorithms/radix_sort.c @@ -59,6 +59,14 @@ void radix_sort(int arr[], int n) return; } + for (int i = 0; i < n; i++) + { + if (arr[i] < 0) + { + return; + } + } + int max = get_max(arr, n); for (int exp = 1; max / exp > 0; exp *= 10)