重构
This commit is contained in:
+55
-69
@@ -1,99 +1,85 @@
|
||||
#include <c_LinkStack.h>
|
||||
#include <c_Memory.h>
|
||||
#include "c_Alignment.h"
|
||||
#include "c_Macros.h"
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
|
||||
c_err_t c_LinkStack_Init(c_LinkStack_t* self, int obj_size) {
|
||||
if (!self || obj_size <= 0) return C_ERR_PARAM;
|
||||
self->head = NULL;
|
||||
self->obj_size = obj_size;
|
||||
#define STACK_NODE_DATA(node) ((void*)((char*)(node) + sizeof(c_LinkStackNode_t)))
|
||||
|
||||
// 原地初始化:无哨兵模式,初始化栈顶 top 为 0 (NULL)
|
||||
c_err_t c_LinkStack_Init(c_LinkStack_t* self, c_size_t item_size, c_Allocator_t* allocator) {
|
||||
if (!self || item_size == 0) return C_ERR_PARAM;
|
||||
|
||||
self->allocator = (allocator != NULL) ? *allocator : c_DefaultAllocator;
|
||||
self->item_size = item_size;
|
||||
self->size = 0;
|
||||
self->top = NULL;
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
// 銷毀堆疊並釋放所有配置的節點與資料記憶體
|
||||
void c_LinkStack_Destroy(c_LinkStack_t* self) {
|
||||
if (!self) return;
|
||||
// 入栈操作 (完美的真正 O(1) 极致无跳转头插)
|
||||
c_err_t c_LinkStack_Push(c_LinkStack_t* self, const void* item) {
|
||||
if (!self || !item) return C_ERR_PARAM;
|
||||
|
||||
c_LinkStackNode_t* current = self->head;
|
||||
while (current != NULL) {
|
||||
c_LinkStackNode_t* next = current->next;
|
||||
C_FREE(current);
|
||||
current = next;
|
||||
}
|
||||
self->head = NULL;
|
||||
self->size = 0;
|
||||
}
|
||||
|
||||
// 推入元素:採用頭插法實作 O(1) 頂端推入,並深複製資料內容
|
||||
c_err_t c_LinkStack_Push(c_LinkStack_t* self, void* obj) {
|
||||
if (!self || !obj) return C_ERR_PARAM;
|
||||
int size = sizeof(c_LinkStackNode_t) + self->obj_size;
|
||||
size = C_ALIGN_UPB(size, C_ALIGN_SIZE);
|
||||
|
||||
c_LinkStackNode_t* new_node = (c_LinkStackNode_t*)C_ALLOC(size);
|
||||
// 1. 动态分配变长节点空间 (控制壳 + 业务数据一体化)
|
||||
c_size_t total_bytes = sizeof(c_LinkStackNode_t) + self->item_size;
|
||||
c_LinkStackNode_t* new_node = (c_LinkStackNode_t*)c_Allocator_Alloc(&self->allocator, total_bytes);
|
||||
if (!new_node) return C_ERR_NOMEM;
|
||||
new_node->data = new_node+1;
|
||||
|
||||
// 值複製 (Value Copy)
|
||||
memcpy(new_node->data, obj, self->obj_size);
|
||||
// 2. 泛型值深度复制
|
||||
memcpy(STACK_NODE_DATA(new_node), item, self->item_size);
|
||||
|
||||
// 頭插法連結
|
||||
new_node->next = self->head;
|
||||
self->head = new_node;
|
||||
// 3. 无边界头插拓扑串联:新节点咬住当前的 top,再让 top 沦为新节点
|
||||
new_node->next = self->top;
|
||||
self->top = new_node;
|
||||
|
||||
self->size++;
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
// 彈出頂端元素:將 `head` 的資料值複製給使用者,隨後釋放該前端節點 (O(1))
|
||||
c_err_t c_LinkStack_Pop(c_LinkStack_t* self, void* obj) {
|
||||
if (!self || !obj) return C_ERR_PARAM;
|
||||
if (self->size == 0 || !self->head) return C_ERR_EMPTY;
|
||||
// 出栈操作 (O(1) 性能,深度拷贝至外部缓冲区,完美防御下溢)
|
||||
c_err_t c_LinkStack_Pop(c_LinkStack_t* self, void* out_item) {
|
||||
if (!self || self->size == 0 || !self->top) return C_ERR_OUTOFBOUND;
|
||||
|
||||
c_LinkStackNode_t* to_delete = self->head;
|
||||
// 锁定即将被弹出解体的栈顶节点
|
||||
c_LinkStackNode_t* node_to_free = self->top;
|
||||
|
||||
// 將資料複製到呼叫端提供的緩衝區
|
||||
memcpy(obj, to_delete->data, self->obj_size);
|
||||
// 如果外部需要拷出数据快照,执行 memcpy
|
||||
if (out_item) {
|
||||
memcpy(out_item, STACK_NODE_DATA(node_to_free), self->item_size);
|
||||
}
|
||||
|
||||
// 斷開頂端節點,head 指向下一個
|
||||
self->head = to_delete->next;
|
||||
|
||||
// 釋放資源
|
||||
C_FREE(to_delete);
|
||||
// 栈顶指针顺理成章移向下一个更早入栈的项
|
||||
self->top = node_to_free->next;
|
||||
|
||||
// 闭环通过内置分配器归还物理块资源
|
||||
c_Allocator_Free(&self->allocator, node_to_free);
|
||||
self->size--;
|
||||
|
||||
return C_ERR_OK;
|
||||
}
|
||||
|
||||
// 查看目前最頂端的元素指標 (O(1),不移除節點)
|
||||
void* c_LinkStack_Peek(c_LinkStack_t* self) {
|
||||
if (!self || !self->head || self->size == 0) return NULL;
|
||||
return self->head->data;
|
||||
// 查看栈顶元素 (只读原位原位窥探,零拷贝损耗)
|
||||
void* c_LinkStack_Peek(const c_LinkStack_t* self) {
|
||||
if (!self || self->size == 0 || !self->top) return NULL;
|
||||
return STACK_NODE_DATA(self->top);
|
||||
}
|
||||
|
||||
void c_LinkStackIter_Remove(c_LinkStackIter_t* self) {
|
||||
// 防呆檢查:確保迭代器有效、繫結的堆疊存在,且當前指向的節點不為空
|
||||
if (!self || !self->stack || !self->node || !*(self->node)) return;
|
||||
// 高效清空栈内全部节点
|
||||
void c_LinkStack_Clear(c_LinkStack_t* self) {
|
||||
if (!self) return;
|
||||
|
||||
c_LinkStackNode_t* to_delete = *(self->node);
|
||||
c_LinkStackNode_t* curr = self->top;
|
||||
while (curr) {
|
||||
c_LinkStackNode_t* next_to_free = curr->next;
|
||||
c_Allocator_Free(&self->allocator, curr);
|
||||
curr = next_to_free;
|
||||
}
|
||||
|
||||
// 關鍵指標轉移:
|
||||
// 將當前結構中維護的指標(可能是前一節點的 next,或是 stack 的 head)
|
||||
// 修改為指向下一個節點,直接從鏈結串列中斷開該節點
|
||||
*(self->node) = to_delete->next;
|
||||
self->top = NULL; // 还原到你 Init 指定的 0 纯净空空空状态
|
||||
self->size = 0;
|
||||
}
|
||||
|
||||
// 釋放節點內深複製的資料空間與節點結構本體
|
||||
C_FREE(to_delete);
|
||||
|
||||
// 同步遞減堆疊的總大小
|
||||
self->stack->size--;
|
||||
|
||||
// 注意:由於 *(self->node) 已被賦值為 to_delete->next,
|
||||
// self->node 目前已自動指向了原本的下一個節點。
|
||||
// 使用者不需要再手動呼叫 Next(),即可直接對新位置進行 Get()、Next() 或再次 Remove()。
|
||||
// 彻底销毁
|
||||
void c_LinkStack_Destroy(c_LinkStack_t* self) {
|
||||
if (!self) return;
|
||||
c_LinkStack_Clear(self);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user