Files
cKit/Foundation/c_LinkStack.c
T
2026-08-29 01:50:50 +08:00

100 lines
3.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
self->size = 0;
return C_ERR_OK;
}
// 銷毀堆疊並釋放所有配置的節點與資料記憶體
void c_LinkStack_Destroy(c_LinkStack_t* self) {
if (!self) return;
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);
if (!new_node) return C_ERR_NOMEM;
new_node->data = new_node+1;
// 值複製 (Value Copy)
memcpy(new_node->data, obj, self->obj_size);
// 頭插法連結
new_node->next = self->head;
self->head = 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;
c_LinkStackNode_t* to_delete = self->head;
// 將資料複製到呼叫端提供的緩衝區
memcpy(obj, to_delete->data, self->obj_size);
// 斷開頂端節點,head 指向下一個
self->head = to_delete->next;
// 釋放資源
C_FREE(to_delete);
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_LinkStackIter_Remove(c_LinkStackIter_t* self) {
// 防呆檢查:確保迭代器有效、繫結的堆疊存在,且當前指向的節點不為空
if (!self || !self->stack || !self->node || !*(self->node)) return;
c_LinkStackNode_t* to_delete = *(self->node);
// 關鍵指標轉移:
// 將當前結構中維護的指標(可能是前一節點的 next,或是 stack 的 head
// 修改為指向下一個節點,直接從鏈結串列中斷開該節點
*(self->node) = to_delete->next;
// 釋放節點內深複製的資料空間與節點結構本體
C_FREE(to_delete);
// 同步遞減堆疊的總大小
self->stack->size--;
// 注意:由於 *(self->node) 已被賦值為 to_delete->next
// self->node 目前已自動指向了原本的下一個節點。
// 使用者不需要再手動呼叫 Next(),即可直接對新位置進行 Get()、Next() 或再次 Remove()。
}