边的核心操作都添测试通过了,但是我个人觉得写的不好。后续再考虑优化。

This commit is contained in:
建峰 2025-04-25 18:19:22 +08:00
parent c411ee96eb
commit 3ac92de18e
3 changed files with 142 additions and 25 deletions

View File

@ -13,6 +13,14 @@
#include "common.h" #include "common.h"
enum _graph_type
{
GRAPH_UNDIRECTED,
GRAPH_DIRECTED,
// GRAPH_UNDIRECTED_WEIGHT,
// GRAPH_DIRECTED_WEIGHT,
};
struct _graph_edge struct _graph_edge
{ {
uint32_t weight; uint32_t weight;
@ -38,6 +46,7 @@ struct _graph
uint32_t _capacity; uint32_t _capacity;
uint32_t _ratio; uint32_t _ratio;
enum _graph_type _type;
struct _iterator _iter; struct _iterator _iter;
void (*_destory)(struct _graph* self); void (*_destory)(struct _graph* self);
@ -83,7 +92,7 @@ struct _graph
typedef struct _graph* graph_t; typedef struct _graph* graph_t;
graph_t graph_new(uint32_t obj_size); 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); void graph_free(graph_t* graph);

View File

@ -372,7 +372,7 @@ static struct _graph_edge* graph_edge_new(void *target, uint32_t weight)
return new_edge; 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) 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; 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 // from_node add edge
struct _graph_edge* new_edge = graph_edge_new(to_node, weight); struct _graph_edge* new_edge = graph_edge_new(to_node, weight);
if (new_edge == NULL) 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; from_node->edgehead->next = new_edge;
} }
// if graph is undirected if(self->_type == GRAPH_UNDIRECTED)
// to_node add edge
struct _graph_edge* new_edge2 = graph_edge_new(from_node, weight);
if (new_edge2 == NULL)
{ {
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) if (to_node->edgehead == NULL)
{ {
to_node->edgehead = new_edge2; to_node->edgehead = new_edge2;
} }
else else
{ {
new_edge2->next = to_node->edgehead->next; new_edge2->next = to_node->edgehead->next;
to_node->edgehead->next = new_edge2; to_node->edgehead->next = new_edge2;
}
} }
return true; 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) 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; return true;
} }
static bool graph_find_edge(struct _graph* self, void* from, void* to) 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; return true;
} }
@ -707,6 +796,9 @@ static bool graph_init(struct _graph* self, uint32_t obj_size)
self->_head->edgehead = NULL; self->_head->edgehead = NULL;
self->_head->next = NULL; self->_head->next = NULL;
self->_type = GRAPH_UNDIRECTED;
// self->_type = GRAPH_DIRECTED;
self->_destory = graph_destory; self->_destory = graph_destory;
// -------------------- public -------------------- // -------------------- public --------------------

View File

@ -39,6 +39,7 @@ void test_graph_add_vertex(void)
} }
// graph->print(graph); // graph->print(graph);
// test find_vertex
TEST_ASSERT_TRUE(graph->find_vertex(graph, &data[0])); TEST_ASSERT_TRUE(graph->find_vertex(graph, &data[0]));
TEST_ASSERT_TRUE(graph->find_vertex(graph, &data[9])); TEST_ASSERT_TRUE(graph->find_vertex(graph, &data[9]));
TEST_ASSERT_FALSE(graph->find_vertex(graph, &temp)); TEST_ASSERT_FALSE(graph->find_vertex(graph, &temp));
@ -92,12 +93,27 @@ void test_graph_add_edge(void)
graph->print(graph); graph->print(graph);
// test add_edge // 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[1], 12));
TEST_ASSERT_TRUE(graph->add_edge(graph, &data[0], &data[2], 66)); TEST_ASSERT_TRUE(graph->add_edge(graph, &data[0], &data[2], 13));
TEST_ASSERT_TRUE(graph->add_edge(graph, &data[1], &data[3], 77)); 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); 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); graph_free(&graph);
TEST_ASSERT_NULL(graph); TEST_ASSERT_NULL(graph);