/* return 1 if edge (source, sink) exists), 0 otherwise */ static int graph_has_edge_internal(Graph g, int source, int sink, int *weight) { int i; struct edge sinkedge; struct edge *bsearch_result; assert(source >= 0); assert(source < g->n); assert(sink >= 0); assert(sink < g->n); /* default if not found */ *weight = MAXINT; if(graph_out_degree(g, source) >= BSEARCH_THRESHOLD) { /* make sure it is sorted */ if(! g->alist[source]->is_sorted) { qsort(g->alist[source]->list, g->alist[source]->d, sizeof(struct edge), edgecmp); } /* call bsearch to do binary search for us */ sinkedge.sink = sink; sinkedge.weight = GRAPH_DEFAULT_EDGE_WEIGHT; bsearch_result = bsearch(&sinkedge, g->alist[source]->list, g->alist[source]->d, sizeof(struct edge), edgecmp); if(bsearch_result != 0) { *weight = bsearch_result->weight; return 1; } else { return 0; } } else { /* just do a simple linear search */ /* we could call lfind for this, but why bother? */ for(i = 0; i < g->alist[source]->d; i++) { if(g->alist[source]->list[i].sink == sink) { *weight = g->alist[source]->list[i].weight; return 1; } } /* else */ return 0; } }
/* return true if edge (source, sink) exists, false otherwise */ static bool graph_edge_exists_internal(graph_t *graph, int source, int sink, int *weight) { int i; adj_list_t *list; edge_t sink_edge; edge_t *bsearch_result; if (!graph || source < 0 || source >= graph->vertices || sink < 0 || sink >= graph->vertices || !graph->adj_list[source]) return -1; if (weight) *weight = INT_MAX; list = graph->adj_list[source]; if (graph_out_degree(graph, source) >= BSEARCH_THRESHOLD) { /* qsort && bsearch */ if (! list->is_sorted) { qsort(list, list->count, sizeof(edge_t), edge_cmp); } sink_edge.sink = sink; sink_edge.weight = GRAPH_DEFAULT_WEIGHT; bsearch_result = bsearch(&sink_edge, list->edges, list->count, sizeof(edge_t), edge_cmp); if (bsearch_result != 0) { if (weight) *weight = bsearch_result->weight; return true; } else { return false; } } else { for (i=0; i<list->count; i++) { if (list->edges[i].sink == sink) { if (weight) *weight = list->edges[i].weight; return true; } } return false; } }
int main(int argc, char **argv){ Graph g; int i; int j; g = graph_create(TEST_SIZE); assert(graph_vertex_count(g) == TEST_SIZE); for (i = 0; i < TEST_SIZE; i++){ for (j = 0; j < TEST_SIZE; j++){ assert(graph_has_edge(g, i, j) == 0); } } for (i = 0; i < TEST_SIZE; i++){ assert(graph_out_degree(g, i) == 0); graph_foreach(g, i, match_sink, 0); } assert(graph_edge_count(g) == 0); for (i = 0; i < TEST_SIZE; i++){ for (j = 0; j < TEST_SIZE; j++){ if (i < j){ graph_add_edge(g, i, j); } } } for (i = 0; i < TEST_SIZE; i++){ for (j = 0; j < TEST_SIZE; j++){ assert(graph_has_edge(g, i, j) == (i < j)); } } assert(graph_edge_count(g) == (TEST_SIZE*(TEST_SIZE-1)/2)); graph2dot(g); graph_destroy(g); return 0; }
/* return 1 if edge (source, sink) exists), 0 otherwise */ int graph_has_edge(Graph g, int source, int sink) { int i; assert(source >= 0); assert(source < g->n); assert(sink >= 0); assert(sink < g->n); if (graph_out_degree(g, source) >= BSEARCH_THRESHOLD) { /* make sure it is sorted */ if (! g->alist[source]->is_sorted) { qsort(g->alist[source]->list, g->alist[source]->d, sizeof(int), intcmp); } /* call bsearch to do binary search for us */ return bsearch(&sink, g->alist[source]->list, g->alist[source]->d, sizeof(int), intcmp) != 0; } else { /* just do a simple linear search */ /* we could call lfind for this, but why bother? */ for (i = 0; i < g->alist[source]->d; i++) { if (g->alist[source]->list[i] == sink) return 1; } /* else */ return 0; } }