64 lines
2.0 KiB
C
64 lines
2.0 KiB
C
#include <c_GraphDFS.h>
|
|
|
|
// Internal recursive helper function that tracks execution states down the stack frames
|
|
static c_bool_t c_Graph_DFS_Internal(
|
|
const c_Graph_t* self,
|
|
c_size_t current_vertex,
|
|
c_bool_t* visited,
|
|
c_Graph_DFS_Callback callback,
|
|
void* context)
|
|
{
|
|
// Mark node as discovered
|
|
visited[current_vertex] = C_TRUE;
|
|
|
|
// Execute user callback function. If it returns false, bubble up to trigger an early abort.
|
|
if (callback && !callback(current_vertex, context)) {
|
|
return C_FALSE;
|
|
}
|
|
|
|
const c_AdjList_t* neighbors = &self->adj_list[current_vertex];
|
|
|
|
// Cache-friendly sequential scan over the contiguous array of primitive integer neighbors
|
|
for (c_size_t i = 0; i < neighbors->size; i++) {
|
|
c_uint_t neighbor = neighbors->array[i];
|
|
|
|
if (!visited[neighbor]) {
|
|
// Recurse into unvisited neighbors. Propagate abort commands immediately.
|
|
if (!c_Graph_DFS_Internal(self, neighbor, visited, callback, context)) {
|
|
return C_FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return C_TRUE; // Continue searching normally
|
|
}
|
|
|
|
c_err_t c_Graph_DFS(const c_Graph_t* self, c_size_t src_vertex, c_Graph_DFS_Callback callback, void* context, c_Allocator_t* allocator) {
|
|
if (!self || src_vertex >= self->V) {
|
|
return C_ERR_PARAM;
|
|
}
|
|
|
|
if (self->V == 0) {
|
|
return C_SUCCESS;
|
|
}
|
|
|
|
allocator = allocator?allocator:&c_DefaultAllocator;
|
|
|
|
// Allocate tracking memory via the graph's configured allocator
|
|
c_bool_t* visited = (c_bool_t*)c_Allocator_Alloc(allocator, self->V * sizeof(c_bool_t));
|
|
if (!visited) {
|
|
return C_ERR_NOMEM;
|
|
}
|
|
|
|
// Initialize all tracking slots to false
|
|
memset(visited, 0, self->V * sizeof(c_bool_t));
|
|
|
|
// Launch the deep structural recursive traversal engine
|
|
c_Graph_DFS_Internal(self, src_vertex, visited, callback, context);
|
|
|
|
// Safely free the temporary visited array tracking memory bounds
|
|
c_Allocator_Free(allocator, visited);
|
|
|
|
return C_SUCCESS;
|
|
}
|