Graph
This commit is contained in:
@@ -1,109 +1 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user