开始设计
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
#include <c_LinkDQueue.h>
|
||||
#include <c_Memory.h>
|
||||
#include <c_Alignment.h>
|
||||
|
||||
C_STATIC_FORCE_INLINE
|
||||
c_LinkDQueueNode_t* create_node(int obj_size, void* obj) {
|
||||
int size = sizeof(c_LinkDQueueNode_t) + obj_size;
|
||||
size = C_ALIGN_UPB(size, C_ALIGN_SIZE);
|
||||
|
||||
c_LinkDQueueNode_t* new_node = (c_LinkDQueueNode_t*)C_ALLOC(size);
|
||||
if (!new_node) return NULL;
|
||||
new_node->data = new_node + 1;
|
||||
|
||||
memcpy(new_node->data, obj, obj_size);
|
||||
new_node->prev = NULL;
|
||||
new_node->next = NULL;
|
||||
return new_node;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||
/* */
|
||||
|
||||
c_err_t c_LinkDQueue_Init(c_LinkDQueue_t* self, int obj_size) {
|
||||
if (!self || obj_size <= 0) return C_ERR_PARAM;
|
||||
self->head = NULL;
|
||||
self->tail = NULL;
|
||||
self->obj_size = obj_size;
|
||||
self->size = 0;
|
||||
return C_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
void c_LinkDQueue_Destroy(c_LinkDQueue_t* self) {
|
||||
if (!self) return;
|
||||
c_LinkDQueueNode_t* current = self->head;
|
||||
while (current != NULL) {
|
||||
c_LinkDQueueNode_t* next = current->next;
|
||||
C_FREE(current);
|
||||
current = next;
|
||||
}
|
||||
self->head = NULL;
|
||||
self->tail = NULL;
|
||||
self->size = 0;
|
||||
}
|
||||
|
||||
// 前端推入 O(1)
|
||||
c_err_t c_LinkDQueue_PushHead(c_LinkDQueue_t* self, void* obj) {
|
||||
if (!self || !obj) return C_ERR_PARAM;
|
||||
c_LinkDQueueNode_t* new_node = create_node(self->obj_size, obj);
|
||||
if (!new_node) return C_ERR_NOMEM;
|
||||
|
||||
if (self->size == 0) {
|
||||
self->head = new_node;
|
||||
self->tail = new_node;
|
||||
} else {
|
||||
new_node->next = self->head;
|
||||
self->head->prev = new_node;
|
||||
self->head = new_node;
|
||||
}
|
||||
self->size++;
|
||||
return C_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// 尾端推入 O(1)
|
||||
c_err_t c_LinkDQueue_PushTail(c_LinkDQueue_t* self, void* obj) {
|
||||
if (!self || !obj) return C_ERR_PARAM;
|
||||
c_LinkDQueueNode_t* new_node = create_node(self->obj_size, obj);
|
||||
if (!new_node) return C_ERR_NOMEM;
|
||||
|
||||
if (self->size == 0) {
|
||||
self->head = new_node;
|
||||
self->tail = new_node;
|
||||
} else {
|
||||
new_node->prev = self->tail;
|
||||
self->tail->next = new_node;
|
||||
self->tail = new_node;
|
||||
}
|
||||
self->size++;
|
||||
return C_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// 前端彈出 O(1)
|
||||
c_err_t c_LinkDQueue_PopHead(c_LinkDQueue_t* self, void* obj) {
|
||||
if (!self || !obj) return C_ERR_PARAM;
|
||||
if (self->size == 0) return C_ERR_EMPTY;
|
||||
|
||||
c_LinkDQueueNode_t* to_delete = self->head;
|
||||
memcpy(obj, to_delete->data, self->obj_size);
|
||||
|
||||
self->head = to_delete->next;
|
||||
if (self->head == NULL) {
|
||||
self->tail = NULL; // 變空佇列
|
||||
} else {
|
||||
self->head->prev = NULL;
|
||||
}
|
||||
|
||||
C_FREE(to_delete);
|
||||
self->size--;
|
||||
return C_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
// 尾端彈出 O(1)
|
||||
c_err_t c_LinkDQueue_PopTail(c_LinkDQueue_t* self, void* obj) {
|
||||
if (!self || !obj) return C_ERR_PARAM;
|
||||
if (self->size == 0) return C_ERR_EMPTY;
|
||||
|
||||
c_LinkDQueueNode_t* to_delete = self->tail;
|
||||
memcpy(obj, to_delete->data, self->obj_size);
|
||||
|
||||
self->tail = to_delete->prev;
|
||||
if (self->tail == NULL) {
|
||||
self->head = NULL; // 變空佇列
|
||||
} else {
|
||||
self->tail->next = NULL;
|
||||
}
|
||||
|
||||
C_FREE(to_delete);
|
||||
self->size--;
|
||||
return C_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
void* c_LinkDQueue_PeekHead(c_LinkDQueue_t* self) {
|
||||
if (!self || self->size == 0) return NULL;
|
||||
return self->head->data;
|
||||
}
|
||||
|
||||
void* c_LinkDQueue_PeekTail(c_LinkDQueue_t* self) {
|
||||
if (!self || self->size == 0) return NULL;
|
||||
return self->tail->data;
|
||||
}
|
||||
|
||||
// 迭代器安全刪除:利用雙向指標在 O(1) 修正前後驅關係並安全維護 head/tail
|
||||
void c_LinkDQueueIter_Remove(c_LinkDQueueIter_t* self) {
|
||||
if (!self || !self->dqueue || !self->node || !*(self->node)) return;
|
||||
|
||||
c_LinkDQueueNode_t* to_delete = *(self->node);
|
||||
c_LinkDQueue_t* dq = self->dqueue;
|
||||
|
||||
// 1. 修正前驅節點的 next 或主結構的 head
|
||||
*(self->node) = to_delete->next;
|
||||
|
||||
// 2. 修正後繼節點的 prev 或主結構的 tail
|
||||
if (to_delete->next != NULL) {
|
||||
to_delete->next->prev = to_delete->prev;
|
||||
} else {
|
||||
dq->tail = to_delete->prev; // 刪除的是尾端,更新 tail
|
||||
}
|
||||
|
||||
// 3. 釋放資源與修正大小
|
||||
C_FREE(to_delete);
|
||||
dq->size--;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user