Graph Start

This commit is contained in:
2026-09-05 13:36:43 +08:00
parent 4e5ae52e54
commit 1564716731
9 changed files with 844 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
#include <c_AdjList.h>
c_err_t c_AdjList_Init(c_AdjList_t* self, c_size_t capacity, c_Allocator_t* allocator) {
if (!self ) return C_ERR_PARAM;
self->allocator = (allocator!=NULL)?*allocator:c_DefaultAllocator;
self->capacity = capacity;
self->size = 0;
if (capacity > 0) {
self->array = c_Allocator_Alloc(&self->allocator, self->capacity * sizeof(*self->array));
if (!self->array) {
self->capacity = 0;
return C_ERR_NOMEM;
}
}else {
self->array = NULL;
}
return C_ERR_OK;
}
void c_AdjList_Destroy(c_AdjList_t* self) {
if (!self) return;
if (self->array && self->allocator.free) {
c_Allocator_Free(&self->allocator, self->array);
self->array = NULL;
}
self->size = 0;
self->capacity = 0;
}
c_err_t c_AdjList_Resize(c_AdjList_t* self, c_size_t new_capacity) {
if (!self) return C_ERR_PARAM;
if (new_capacity == self->capacity) return C_ERR_OK;
// Boundary contract protection: Cap cannot compress below active item footprints
if (new_capacity < self->size) return C_ERR_PARAM;
if (new_capacity == 0) {
if (self->array) {
c_Allocator_Free(&self->allocator, self->array);
self->array = NULL;
}
self->capacity = 0;
return C_ERR_OK;
}
c_uint_t* new_ptr = NULL;
if (self->array) {
c_size_t old_size = self->capacity * sizeof(*self->array);
c_size_t new_size = new_capacity * sizeof(*self->array);
new_ptr = c_Allocator_Realloc(&self->allocator, self->array, old_size, new_size);
} else {
new_ptr = c_Allocator_Alloc(&self->allocator, new_capacity * sizeof(*self->array));
}
if (!new_ptr) return C_ERR_NOMEM;
self->array = new_ptr;
self->capacity = new_capacity;
return C_ERR_OK;
}
c_err_t c_AdjList_Append(c_AdjList_t* self, c_uint_t value) {
if (!self) return C_ERR_PARAM;
// Geometric resizing policy (doubling capacity on saturation)
if (self->size >= self->capacity) {
c_size_t next_cap = (self->capacity == 0) ? 4 : (self->capacity << 1);
c_err_t err = c_AdjList_Resize(self, next_cap);
if (err != C_ERR_OK) return err;
}
self->array[self->size++] = value;
return C_ERR_OK;
}
c_err_t c_AdjList_Set(c_AdjList_t* self, c_size_t index, c_uint_t value) {
if (!self || index >= self->size) return C_ERR_PARAM;
self->array[index] = value;
return C_ERR_OK;
}
c_err_t c_AdjList_Get(c_AdjList_t* self, c_size_t index, c_uint_t* value) {
if (!self || !value || index >= self->size) return C_ERR_PARAM;
if (value) {
*value = self->array[index];
}
return C_ERR_OK;
}
c_err_t c_AdjList_Remove(c_AdjList_t* self, c_size_t index) {
if (!self || index >= self->size) return C_ERR_PARAM;
c_size_t elements_to_move = self->size - index - 1;
if (elements_to_move > 0) {
memmove(&self->array[index], &self->array[index + 1], elements_to_move * sizeof(c_uint_t));
}
self->size--;
if (self->size <= (self->capacity>>2)) {
return c_AdjList_Resize(self, self->capacity >> 1);
}
return C_ERR_OK;
}