在学习QAT开源框架过程中,发现代码中的双向链表写的非常好,特此记录下来,以备不时之需。好了,废话不多说,下面主要以实例的形式展示双向链表的写法。
1. 双向链表结构体
typedef struct registation_handle_s
{
Status (*EventHandler)(accel_dev_t *accel_dev,
enum adf_event event,
void *param);
char *name;
struct registation_handle_s *pNext; /* 下一个元素 */
struct registation_handle_s *pPrev; /* 上一个元素 */
} registation_handle_t;
static registation_handle_t *pSubsystemTable = NULL; /* 指向链表的尾 */
static registation_handle_t *pSubsystemTableHead = NULL; /* 指向链表的头 */
2. 在链表的头添加一个元素
/* Macro for adding an element to the head of a doubly linked list */
/* The currentptr tracks the tail, and the headptr tracks the head */
#define ICP_ADD_ELEMENT_TO_HEAD_OF_LIST(elementtoadd, currentptr, headptr) \
do \
{
\
if (NULL == headptr) /* 链表为空链表 */ \
{
\
elementtoadd->pNext = NULL; \
elementtoadd->pPrev = NULL; \
headptr = elementtoadd; \
} \
else \
{
\
elementtoadd->pPrev = NULL; \
elementtoadd->pNext = headptr; \
headptr->pPrev = elementtoadd; \
headptr = elementtoadd; \
} \
} while (0)
3. 在链表的尾添加一个元素
/* Macro for adding an element to the tail of a doubly linked list */
/* The currentptr tracks the tail, and the headptr tracks the head */
#define ICP_ADD_ELEMENT_TO_END_OF_LIST(elementtoadd, currentptr, headptr) \
do \
{
\
if (NULL == currentptr) /* 链表为空链表 */ \
{
\
currentptr = elementtoadd; \
elementtoadd->pNext = NULL; \
elementtoadd->pPrev = NULL; \
headptr = currentptr; \
} \
else /* 非空链表 */ \
{
\
elementtoadd->pPrev = currentptr; \
currentptr->pNext = elementtoadd; \
elementtoadd->pNext = NULL; \
currentptr = elementtoadd; \
} \
} while (0)
4. 删除链表中的一个元素
#define ICP_REMOVE_ELEMENT_FROM_LIST(elementtoremove, currentptr, headptr) \
do \
{
\
/* If the previous pointer is not NULL */ \
if (NULL != elementtoremove->pPrev) \
{
\
elementtoremove->pPrev->pNext = elementtoremove->pNext; \
if (elementtoremove->pNext) \
{
\
elementtoremove->pNext->pPrev = elementtoremove->pPrev; \
} \
else \
{
\
/* Move the tail pointer backwards */ \
currentptr = elementtoremove->pPrev; \
} \
} \
else if (NULL != elementtoremove->pNext) \
{
\
/* Remove the head pointer */ \
elementtoremove->pNext->pPrev = NULL; \
/* Hence move the head forward */ \
headptr = elementtoremove->pNext; \
} \
else \
{
\
/* Remove the final entry in the list */ \
currentptr = NULL; \
headptr = NULL; \
} \
} while (0)
5. 在链表中查找一个元素
/* Macro to try to find an element in a linked list.
* The Macro compares pointer values between the pointer and the list
* to determine if the pointer is in the list. */
#define ICP_FIND_ELEMENT_IN_LIST(elementtofind, listhead, status) \
do \
{
\
if (NULL == listhead) \
{
\
status = STATUS_FAIL; \
} \
while (listhead != NULL) \
{
\
if (listhead == elementtofind) \
{
\
status = STATUS_SUCCESS; \
break; \
} \
else \
{
\
listhead = listhead->pNext; \
} \
} \
} while (0)
6. 释放链表
/* Macro to free a linked list */
#define ICP_FREE_LIST(current_ptr) \
do \
{
\
if (NULL != current_ptr) \
{
\
while (NULL != current_ptr->pNext) \
{
\
current_ptr = current_ptr->pNext; \
free(current_ptr->pPrev); \
current_ptr->pPrev = NULL; \
} \
free(current_ptr); \
current_ptr = NULL; \
} \
} while (0)