1. 代码说明
功能
staque结构以单链表方式实现,结合了stack与queue结构:pop_front+push_front使用方式为stack;pop_front+push_back使用方式是queue。
除此之外还提供任意位置的插入、删除、访问和获取索引函数,但执行效率不高。
没有提供拷贝复制函数,因为涉及深浅拷贝问题,建议用迭代器自行实现拷贝函数。
迭代器
迭代器struct unidirectional_node也是staque的构成组件。
一般用法:for (P_STRUCT_UD_NODE p_node = p_staque->p_first; p_node != NULL; p_node = p_node->p_next) { ... }
涉及元素增减操作时不建议使用迭代器,因为容易造成访问混乱,推荐使用计数方式。
返回值
对所有带返回值的函数来说:返回值如果是void*类型,则NULL代表执行失败;如果是int类型,则0为成功,-1为失败。
销毁
调用f_staque_destory()销毁一个staque结构对象时注意,它将自动弹出所有元素(如果有),务必做好内存管理。
2. 代码实现
staque.h
1 #ifndef __STAQUE_H 2 #define __STAQUE_H 3 4 typedef 5 struct unidirectional_node 6 { 7 void* p_data; 8 struct unidirectional_node* p_next; 9 }STRUCT_UD_NODE, 10 * P_STRUCT_UD_NODE; 11 12 typedef 13 struct staque 14 { 15 unsigned int count; 16 P_STRUCT_UD_NODE p_first; 17 P_STRUCT_UD_NODE p_last; 18 }STRUCT_STAQUE, 19 * P_STRUCT_STAQUE; 20 21 P_STRUCT_STAQUE 22 f_staque_construct(void); 23 24 void 25 f_staque_push_back(P_STRUCT_STAQUE const p_stq, void* const p_data); 26 27 void 28 f_staque_push_front(P_STRUCT_STAQUE const p_stq, void* const p_data); 29 30 void* 31 f_staque_pop_front(P_STRUCT_STAQUE const p_stq); 32 33 int 34 f_staque_data_insert(P_STRUCT_STAQUE const p_stq, void* const p_data, const unsigned int index); 35 36 void* 37 f_staque_data_remove(P_STRUCT_STAQUE const p_stq, const unsigned int index); 38 39 void* 40 f_staque_data_access(P_STRUCT_STAQUE const p_stq, const unsigned int index); 41 42 int 43 f_staque_data_index(P_STRUCT_STAQUE const p_stq, void* const p_data, unsigned int* const p_index); 44 45 void 46 f_staque_destroy(P_STRUCT_STAQUE const p_stq); 47 48 #endif // !__STAQUE_H
staque.c
1 #include "staque.h" 2 #include <stdlib.h> 3 4 #pragma warning(disable:6011) 5 6 P_STRUCT_STAQUE f_staque_construct(void) 7 { 8 P_STRUCT_STAQUE p_ret_stq = (P_STRUCT_STAQUE)malloc(sizeof(STRUCT_STAQUE)); 9 p_ret_stq->count = 0; 10 p_ret_stq->p_first = NULL; 11 p_ret_stq->p_last = NULL; 12 return p_ret_stq; 13 } 14 15 void innf_add_first_node(P_STRUCT_STAQUE const p_stq, void* const p_data) 16 { 17 p_stq->p_first = (P_STRUCT_UD_NODE)malloc(sizeof(STRUCT_UD_NODE)); 18 p_stq->p_first->p_data = p_data; 19 p_stq->p_first->p_next = NULL; 20 p_stq->p_last = p_stq->p_first; 21 p_stq->count = 1; 22 } 23 24 void* innf_remove_last_node(P_STRUCT_STAQUE const p_stq) 25 { 26 void* p_ret_data = p_stq->p_first->p_data; 27 free(p_stq->p_first); 28 p_stq->p_first = NULL; 29 p_stq->p_last = NULL; 30 p_stq->count = 0; 31 return p_ret_data; 32 } 33 34 void f_staque_push_back(P_STRUCT_STAQUE const p_stq, void* const p_data) 35 { 36 switch (p_stq->count) 37 { 38 case 0: 39 innf_add_first_node(p_stq, p_data); 40 return; 41 } 42 P_STRUCT_UD_NODE p_node = (P_STRUCT_UD_NODE)malloc(sizeof(STRUCT_UD_NODE)); 43 p_node->p_data = p_data; 44 p_node->p_next = NULL; 45 p_stq->p_last->p_next = p_node; 46 p_stq->p_last = p_node; 47 p_stq->count++; 48 } 49 50 void f_staque_push_front(P_STRUCT_STAQUE const p_stq, void* const p_data) 51 { 52 switch (p_stq->count) { 53 case 0: 54 innf_add_first_node(p_stq, p_data); 55 return; 56 } 57 P_STRUCT_UD_NODE p_node = (P_STRUCT_U