mirror of
https://gitee.com/apaki/unicstl.git
synced 2025-07-03 23:56:54 +08:00
边的核心操作都添测试通过了,但是我个人觉得写的不好。后续再考虑优化。
This commit is contained in:
parent
c411ee96eb
commit
3ac92de18e
@ -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);
|
||||||
|
|
||||||
|
132
src/graph.c
132
src/graph.c
@ -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 --------------------
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user