diff --git a/include/graph.h b/include/graph.h index cc06a2a..bdbb89d 100644 --- a/include/graph.h +++ b/include/graph.h @@ -77,7 +77,7 @@ struct _graph bool (*full)(struct _graph* self); // iter - iterator_t (*iter)(struct _graph* self); + iterator_t (*iter)(struct _graph* self, void *obj); // config compare_fun_t compare; // !!! you have to implement this function diff --git a/src/graph.c b/src/graph.c index f526ace..d421d59 100644 --- a/src/graph.c +++ b/src/graph.c @@ -772,6 +772,56 @@ static bool graph_find_edge(struct _graph* self, void* from, void* to) return true; } + +iterator_t graph_iter(struct _graph* self, void* start_obj) +{ + assert(self != NULL); + iterator_t iter = &self->_iter; + + iter->_parent = self; + iter->_cur = 0; + iter->_cur_node = self->_head; + + struct _graph_node* start = find_node(self, start_obj); + if(start != NULL) + { + iter->_cur_node = start; + } + return iter; +} + +bool graph_iter_hasnext(struct _iterator* iter) +{ + assert(iter != NULL); + assert(iter->parent != NULL); + + graph_t self = (graph_t)iter->_parent; + if(iter->_cur < self->size(self)) + { + return true; + } + return false; +} + +const void* graph_iter_next(struct _iterator* iter) +{ + assert(iter != NULL); + assert(iter->parent != NULL); + + graph_t self = (graph_t)iter->_parent; + void *obj = NULL; + + // base on linklist + struct _graph_node * node = (struct _graph_node *)iter->_cur_node; + if(node != NULL) + { + obj = node->obj; + iter->_cur_node = node->next; + } + self->_iter._cur += 1; + return obj; +} + static bool graph_init(struct _graph* self, uint32_t obj_size) { assert(self != NULL); @@ -799,6 +849,9 @@ static bool graph_init(struct _graph* self, uint32_t obj_size) self->_type = GRAPH_UNDIRECTED; // self->_type = GRAPH_DIRECTED; + self->_iter.hasnext = graph_iter_hasnext; + self->_iter.next = graph_iter_next; + self->_destory = graph_destory; // -------------------- public -------------------- @@ -818,6 +871,10 @@ static bool graph_init(struct _graph* self, uint32_t obj_size) self->empty = graph_empty; self->capacity = graph_capacity; + // iter + self->iter = graph_iter; + + // others self->from_matrix = NULL; self->bfs = NULL; self->dfs = NULL; diff --git a/test/test_graph.c b/test/test_graph.c index ce61549..f5fdd28 100644 --- a/test/test_graph.c +++ b/test/test_graph.c @@ -90,7 +90,7 @@ void test_graph_add_edge(void) { TEST_ASSERT_TRUE(graph->add_vertex(graph, &data[i])); } - graph->print(graph); + //graph->print(graph); // test add_edge TEST_ASSERT_TRUE(graph->add_edge(graph, &data[0], &data[1], 12)); @@ -98,7 +98,7 @@ void test_graph_add_edge(void) 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 find_edge TEST_ASSERT_TRUE(graph->find_edge(graph, &data[0], &data[1])); @@ -109,16 +109,63 @@ void test_graph_add_edge(void) // test del_edge TEST_ASSERT_TRUE(graph->del_edge(graph, &data[0], &data[1])); - graph->print(graph); + //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->print(graph); graph_free(&graph); TEST_ASSERT_NULL(graph); } +void test_graph_iter(void) +{ + const int size = 10; + int data[10] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + }; + int temp = 11; + uint32_t i = 0; + + graph_t graph = graph_new(sizeof(int)); + TEST_ASSERT_NOT_NULL(graph); + graph->compare = compare_num; + graph->print_obj = print_num; + + // test add_vertex + for(i = 0; i < size; i++) + { + TEST_ASSERT_TRUE(graph->add_vertex(graph, &data[i])); + } + // graph->print(graph); + + // test add_edge + 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); + + printf("test iter_vertex: \n"); + iterator_t iter_vertex = graph->iter(graph, &data[0]); + TEST_ASSERT_NOT_NULL(iter_vertex); + + printf("start\n"); + while(iter_vertex->hasnext(iter_vertex)) + { + printf("next : "); + temp = *(int *)iter_vertex->next(iter_vertex); + printf("%d\n", temp); + } + printf("end\n"); + + graph_free(&graph); + TEST_ASSERT_NULL(graph); +} + + #if 0 void test_graph_print(void) { @@ -167,6 +214,7 @@ void test_graph(void) RUN_TEST(test_graph_new); RUN_TEST(test_graph_add_vertex); RUN_TEST(test_graph_add_edge); + RUN_TEST(test_graph_iter); // RUN_TEST(test_graph_print); // RUN_TEST(test_graph_from_matrix);