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

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"
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);

View File

@ -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,6 +647,8 @@ static bool graph_add_edge(struct _graph* self, void* from, void* to, uint32_t w
from_node->edgehead->next = new_edge;
}
if(self->_type == GRAPH_UNDIRECTED)
{
// if graph is undirected
// to_node add edge
struct _graph_edge* new_edge2 = graph_edge_new(from_node, weight);
@ -669,17 +666,109 @@ static bool graph_add_edge(struct _graph* self, void* from, void* to, uint32_t w
new_edge2->next = to_node->edgehead->next;
to_node->edgehead->next = new_edge2;
}
}
return true;
}
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 --------------------

View File

@ -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);