From 3ac92de18e732845f7f27ae8cddcde536d1ed0a0 Mon Sep 17 00:00:00 2001 From: wjf-hs Date: Fri, 25 Apr 2025 18:19:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BE=B9=E7=9A=84=E6=A0=B8=E5=BF=83=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E9=83=BD=E6=B7=BB=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87?= =?UTF-8?q?=E4=BA=86=EF=BC=8C=E4=BD=86=E6=98=AF=E6=88=91=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E8=A7=89=E5=BE=97=E5=86=99=E7=9A=84=E4=B8=8D=E5=A5=BD=E3=80=82?= =?UTF-8?q?=E5=90=8E=E7=BB=AD=E5=86=8D=E8=80=83=E8=99=91=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/graph.h | 11 +++- src/graph.c | 132 +++++++++++++++++++++++++++++++++++++++------- test/test_graph.c | 24 +++++++-- 3 files changed, 142 insertions(+), 25 deletions(-) diff --git a/include/graph.h b/include/graph.h index f43cc22..cc06a2a 100644 --- a/include/graph.h +++ b/include/graph.h @@ -13,6 +13,14 @@ #include "common.h" +enum _graph_type +{ + GRAPH_UNDIRECTED, + GRAPH_DIRECTED, + // GRAPH_UNDIRECTED_WEIGHT, + // GRAPH_DIRECTED_WEIGHT, +}; + struct _graph_edge { uint32_t weight; @@ -38,6 +46,7 @@ struct _graph uint32_t _capacity; uint32_t _ratio; + enum _graph_type _type; struct _iterator _iter; void (*_destory)(struct _graph* self); @@ -83,7 +92,7 @@ struct _graph typedef struct _graph* graph_t; graph_t graph_new(uint32_t obj_size); -graph_t graph_new2(uint32_t obj_size, uint32_t capacity); +// graph_t graph_new2(uint32_t obj_size, uint32_t capacity); void graph_free(graph_t* graph); diff --git a/src/graph.c b/src/graph.c index 03c6163..f526ace 100644 --- a/src/graph.c +++ b/src/graph.c @@ -372,7 +372,7 @@ static struct _graph_edge* graph_edge_new(void *target, uint32_t weight) return new_edge; } -static void greph_edge_free(struct _graph_edge** edge) +static void graph_edge_free(struct _graph_edge** edge) { if (edge != NULL && *edge != NULL) { @@ -631,11 +631,6 @@ static bool graph_add_edge(struct _graph* self, void* from, void* to, uint32_t w return false; } - // printf("print from and to obj start \n"); - // self->print_obj(from_node->obj); - // self->print_obj(to_node->obj); - // printf("print from and to obj end \n"); - // from_node add edge struct _graph_edge* new_edge = graph_edge_new(to_node, weight); if (new_edge == NULL) @@ -652,22 +647,25 @@ static bool graph_add_edge(struct _graph* self, void* from, void* to, uint32_t w from_node->edgehead->next = new_edge; } - // if graph is undirected - // to_node add edge - struct _graph_edge* new_edge2 = graph_edge_new(from_node, weight); - if (new_edge2 == NULL) + if(self->_type == GRAPH_UNDIRECTED) { - return false; - } + // if graph is undirected + // to_node add edge + struct _graph_edge* new_edge2 = graph_edge_new(from_node, weight); + if (new_edge2 == NULL) + { + return false; + } - if (to_node->edgehead == NULL) - { - to_node->edgehead = new_edge2; - } - else - { - new_edge2->next = to_node->edgehead->next; - to_node->edgehead->next = new_edge2; + if (to_node->edgehead == NULL) + { + to_node->edgehead = new_edge2; + } + else + { + new_edge2->next = to_node->edgehead->next; + to_node->edgehead->next = new_edge2; + } } return true; @@ -675,11 +673,102 @@ static bool graph_add_edge(struct _graph* self, void* from, void* to, uint32_t w static bool graph_del_edge(struct _graph* self, void* from, void* to) { + assert(self != NULL); + if (self->empty(self)) + { + return false; + } + + struct _graph_node* from_node = self->_head->next; + struct _graph_node* to_node = self->_head->next; + from_node = find_node(self, from); + if (from_node == NULL) + { + return false; + } + + to_node = find_node(self, to); + if (to_node == NULL) + { + return false; + } + + struct _graph_edge* cur = from_node->edgehead; + struct _graph_edge* pre = from_node->edgehead; + while(cur != NULL) + { + if(cur->target == to_node) + { + pre->next = cur->next; + if(pre == cur) + { + from_node->edgehead = cur->next; + } + graph_edge_free(&cur); + break; + } + pre = cur; + cur = cur->next; + } + + if(self->_type == GRAPH_UNDIRECTED) + { + struct _graph_edge* cur2 = to_node->edgehead; + struct _graph_edge* pre2 = to_node->edgehead; + while(cur2 != NULL) + { + if(cur2->target == from_node) + { + pre2->next = cur2->next; + if(pre2 == cur2) + { + to_node->edgehead = cur2->next; + } + graph_edge_free(&cur2); + break; + } + pre2 = cur2; + cur2 = cur2->next; + } + } return true; } static bool graph_find_edge(struct _graph* self, void* from, void* to) { + assert(self != NULL); + if (self->empty(self)) + { + return false; + } + struct _graph_node* from_node = self->_head->next; + struct _graph_node* to_node = self->_head->next; + from_node = find_node(self, from); + if (from_node == NULL) + { + return false; + } + + to_node = find_node(self, to); + if (to_node == NULL) + { + return false; + } + + struct _graph_edge* cur = from_node->edgehead; + while(cur != NULL) + { + if(cur->target == to_node) + { + // found edge + break; + } + cur = cur->next; + } + if(cur == NULL) + { + return false; + } return true; } @@ -707,6 +796,9 @@ static bool graph_init(struct _graph* self, uint32_t obj_size) self->_head->edgehead = NULL; self->_head->next = NULL; + self->_type = GRAPH_UNDIRECTED; + // self->_type = GRAPH_DIRECTED; + self->_destory = graph_destory; // -------------------- public -------------------- diff --git a/test/test_graph.c b/test/test_graph.c index 18d73e0..ce61549 100644 --- a/test/test_graph.c +++ b/test/test_graph.c @@ -39,6 +39,7 @@ void test_graph_add_vertex(void) } // graph->print(graph); + // test find_vertex TEST_ASSERT_TRUE(graph->find_vertex(graph, &data[0])); TEST_ASSERT_TRUE(graph->find_vertex(graph, &data[9])); TEST_ASSERT_FALSE(graph->find_vertex(graph, &temp)); @@ -92,12 +93,27 @@ void test_graph_add_edge(void) graph->print(graph); // test add_edge - TEST_ASSERT_TRUE(graph->add_edge(graph, &data[0], &data[1], 55)); - TEST_ASSERT_TRUE(graph->add_edge(graph, &data[0], &data[2], 66)); - TEST_ASSERT_TRUE(graph->add_edge(graph, &data[1], &data[3], 77)); + TEST_ASSERT_TRUE(graph->add_edge(graph, &data[0], &data[1], 12)); + TEST_ASSERT_TRUE(graph->add_edge(graph, &data[0], &data[2], 13)); + TEST_ASSERT_TRUE(graph->add_edge(graph, &data[1], &data[3], 24)); + TEST_ASSERT_TRUE(graph->add_edge(graph, &data[5], &data[6], 67)); + TEST_ASSERT_FALSE(graph->add_edge(graph, &temp, &data[1], 0)); graph->print(graph); - TEST_ASSERT_FALSE(graph->add_edge(graph, &temp, &data[1], 0)); + // test find_edge + TEST_ASSERT_TRUE(graph->find_edge(graph, &data[0], &data[1])); + TEST_ASSERT_TRUE(graph->find_edge(graph, &data[1], &data[3])); + TEST_ASSERT_TRUE(graph->find_edge(graph, &data[6], &data[5])); // undirected graph + TEST_ASSERT_FALSE(graph->find_edge(graph, &data[4], &data[3])); + TEST_ASSERT_FALSE(graph->find_edge(graph, &data[0], &temp)); + + // test del_edge + TEST_ASSERT_TRUE(graph->del_edge(graph, &data[0], &data[1])); + graph->print(graph); + + TEST_ASSERT_FALSE(graph->find_edge(graph, &data[0], &data[1])); + TEST_ASSERT_TRUE(graph->del_edge(graph, &data[5], &data[6])); + graph->print(graph); graph_free(&graph); TEST_ASSERT_NULL(graph);