修复博客:http://blog.csdn.net/lh806732/article/details/53946839
list_head.h
#pragma once
#ifndef __LIST_HEAD_H__
#define __LIST_HEAD_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#define offsetof(TYPE, MEMBER) (((size_t)(&((TYPE *)0)->MEMBER)))// 得到结构体成员在结构体中的偏移量
#define container_of(ptr, type, member) ((type *)((char *)ptr - offsetof(type, member)))// 得到指向结构体指针的首地址
#define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)// for循环
#define list_for_each_r(pos, head) for (pos = (head)->prev; pos != (head); pos = pos->prev)// 反向for循环
#define list_entry(ptr, type, member) container_of(ptr, type, member)// 根据‘指向结构体list_head_t成员指针’和‘结构体类型’以及结构体中‘list_head_t成员名’得到结构体首地址
typedef struct list_head
{
struct list_head *prev;
struct list_head *next;
} list_head_t, *plist_head_t;
typedef enum list_type
{
TYPE_UNKNOWN = -1,// 未知类型
TYPE_STACK,// 栈类型的列表
TYPE_QUEUE,// 队列类型的列表
} list_type_t;
extern int list_head_init(list_head_t *head);// 初始化表头,使用列表前必须初始化表头
extern int list_push_stack(list_head_t *entry, list_head_t *head);// 作为栈使用,把entry压入到以head为表头的列表中
extern list_head_t *list_pop_stack(list_head_t *head);// 作为栈使用,把以head为表头的列表中的栈顶节点出栈
extern int list_enqueue(list_head_t *entry, list_head_t *head);// 作为队列使用,把entry入列到以head为表头的列表中
extern list_head_t *list_dequeue(list_head_t *head);// 作为队列使用,把以head为表头的列表中队列头的节点出列
extern int list_insert_before(list_head_t *entry, list_head_t *ref, list_type_t type);// 在ref节点的前面插入entry节点
extern int list_insert_after(list_head_t *entry, list_head_t *ref, list_type_t type);// 在ref节点的后面插入entry节点
extern int list_insert(list_head_t *entry, list_head_t *prev, list_head_t *next);// 在prev和next节点之间插入entry节点
extern list_head_t *list_delete_entry(list_head_t *entry, list_head_t *head);// 从以head为表头的列表中删除entry节点,仅仅断开节点,返回断开节点后调用者释放内存
extern int list_is_empty(const list_head_t *head);// 以head为表头的列表是否为空
extern int list_size(const list_head_t *head);// 获取以head为表头的列表的大小
extern int list_splice_to_head(list_head_t *_new, list_head_t *head);// 把新的列表_new合并到以head为表头的列表的头部
extern int list_splice_to_tail(list_head_t *_new, list_head_t *head);// 把新的列表_new合并到以head为表头的列表的尾部
extern int list_replace(list_head_t *_new, list_head_t *old);// 把列表中old节点替换为新的_new节点
extern int list_revese(list_head_t *head);// 把以head为表头的列表中的所有节点前后顺序倒置,倒置后仍然以head为表头
#ifdef __cplusplus
}
#endif
#endif
list_head.c
#include "list_head.h"
#include <stdio.h>
#define LIST_POINT1 ((void *)0x00100100)
#define LIST_POINT2 ((void *)0x00200200)
typedef enum splice_mode
{
SPLICE_UNKNOWN = -1,
SPLICE_HEAD, // 合并列表时把新的列表合并都原有列表的表头
SPLICE_TAIL, // 合并列表时把新的列表合并都原有列表的表尾
} splice_mode_t;
static void __list_add(list_head_t *entry, list_head_t *prev, list_head_t *next);
static void __list_del(list_head_t *entry, list_head_t *prev, list_head_t *next);
static int __list_splice(list_head_t *list, list_head_t *head, splice_mode_t mode);
/***************************************************************************************************
* 函数名:int list_head_init(list_head_t *head)
* 功能描述:初始化表头,使用列表前必须初始化表头
* 输入参数:
* head :列表表头
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_head_init(list_head_t *head)
{
if (NULL == head)
{
return -1;
}
head->prev = head;
head->next = head;
return 0;
}
/***************************************************************************************************
* 函数名:int list_push_stack(list_head_t *entry, list_head_t *head)
* 功能描述:作为栈使用,把entry压入到以head为表头的列表中
* 输入参数:
* entry :待压栈节点
* head : 以head为表头的列表
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_push_stack(list_head_t *entry, list_head_t *head)
{
if (NULL == entry || NULL == head)
{
return -1;
}
__list_add(entry, head, head->next);
return 0;
}
/***************************************************************************************************
* 函数名:list_head_t *list_pop_stack(list_head_t *head)
* 功能描述:作为栈使用,把以head为表头的列表中的栈顶节点出栈
* 输入参数:
* head : 以head为表头的列表
* 输出参数:
* 无
* 返回值:
* 非NULL :成功
* NULL :失败
***************************************************************************************************/
inline list_head_t *list_pop_stack(list_head_t *head)
{
if (list_is_empty(head))
{
return NULL;
}
list_head_t *entry = head->next;
if (head != entry)
{
//list_head_t *next = entry->next;
//head->next = next;
//next->prev = head;
__list_del(entry, entry->prev, entry->next);
return entry;
}
return NULL;
}
/***************************************************************************************************
* 函数名:int list_enqueue(list_head_t *entry, list_head_t *head)
* 功能描述:作为队列使用,把entry入列到以head为表头的列表中
* 输入参数:
* entry :待入列节点
* head : 以head为表头的列表
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_enqueue(list_head_t *entry, list_head_t *head)
{
if (NULL == entry || NULL == head)
{
return -1;
}
__list_add(entry, head->prev, head);
return 0;
}
/***************************************************************************************************
* 函数名:list_head_t *list_dequeue(list_head_t *head)
* 功能描述:作为队列使用,把以head为表头的列表中队列头的节点出列
* 输入参数:
* head : 以head为表头的列表
* 输出参数:
* 无
* 返回值:
* 非NULL :成功
* NULL :失败
***************************************************************************************************/
inline list_head_t *list_dequeue(list_head_t *head)
{
return list_pop_stack(head);
}
inline void __list_add(list_head_t *entry, list_head_t *prev, list_head_t *next)
{
next->prev = entry;
entry->next = next;
entry->prev = prev;
prev->next = entry;
}
/***************************************************************************************************
* 函数名:int list_insert_before(list_head_t *entry, list_head_t *ref, list_type_t type)
* 功能描述:在ref节点的前面插入entry节点
* 输入参数:
* entry : 待插入节点
* ref : 插入点的参考节点
* type : 是否以栈还是队列方式进行操作
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_insert_before(list_head_t *entry, list_head_t *ref, list_type_t type)
{
if (NULL == entry || NULL == ref || TYPE_UNKNOWN == type)
{
return -1;
}
if (ref->prev == ref->next && ref == ref->prev)// 空列表
{
return -1;
}
if (TYPE_STACK == type)// 栈
{
__list_add(entry, ref, ref->next);
}
else if (TYPE_QUEUE == type)// 队列
{
__list_add(entry, ref->prev, ref);
}
return 0;
}
/***************************************************************************************************
* 函数名:int list_insert_after(list_head_t *entry, list_head_t *ref, list_type_t type)
* 功能描述:在ref节点的后面插入entry节点
* 输入参数:
* entry : 待插入节点
* ref : 插入点的参考节点
* type : 是否以栈还是队列方式进行操作
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_insert_after(list_head_t *entry, list_head_t *ref, list_type_t type)
{
if (NULL == entry || NULL == ref || TYPE_UNKNOWN == type)
{
return -1;
}
if (ref->prev == ref->next && ref == ref->prev)// 空列表
{
return -1;
}
if (TYPE_STACK == type)// 栈
{
__list_add(entry, ref->prev, ref);
}
else if (TYPE_QUEUE == type)// 队列
{
__list_add(entry, ref, ref->next);
}
return 0;
}
/***************************************************************************************************
* 函数名:int list_insert(list_head_t *entry, list_head_t *prev, list_head_t *next)
* 功能描述:在prev和next节点之间插入entry节点
* 输入参数:
* entry : 待插入节点
* prev : entry前节点
* next : entry后节点
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_insert(list_head_t *entry, list_head_t *prev, list_head_t *next)
{
if (NULL == entry || NULL == prev || NULL == next)
{
return -1;
}
if ((prev == next) || // 空列表
(prev->prev == prev->next && prev->prev == next))// 列表只有1个节点
{
return -1;// 无节点或1个节点没法插入,返回失败
}
if (prev->next == next)
{
__list_add(entry, prev, next);
}
else if (prev->prev == next)// 调用者把插入点前后传错了
{
__list_add(entry, next, prev);
}
else // 前后节点不相邻
{
return -1;
}
return 0;
}
/***************************************************************************************************
* 函数名:list_head_t *list_delete_entry(list_head_t *entry, list_head_t *head)
* 功能描述:从以head为表头的列表中删除entry节点,仅仅断开节点,返回断开节点后调用者释放内存
* 输入参数:
* entry : 待插入节点
* head : 列表表头
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline list_head_t *list_delete_entry(list_head_t *entry, list_head_t *head)
{
if (list_is_empty(head) || NULL == entry || head == entry)
{
return NULL;
}
__list_del(entry, entry->prev, entry->next);
return entry;
}
inline void __list_del(list_head_t *entry, list_head_t *prev, list_head_t *next)
{
next->prev = prev;
prev->next = next;
#if 0// 编译段错误(内核中)?
entry->prev = LIST_POINT1;
entry->next = LIST_POINT2;
#else
entry->prev = NULL;
entry->next = NULL;
#endif
}
/***************************************************************************************************
* 函数名:int list_is_empty(const list_head_t *head)
* 功能描述:以head为表头的列表是否为空
* 输入参数:
* head : 列表表头
* 输出参数:
* 无
* 返回值:
* 1 :空
* 0 :非空
***************************************************************************************************/
inline int list_is_empty(const list_head_t *head)
{
if (NULL == head)
{
return 1;
}
return head->next == head;
}
/***************************************************************************************************
* 函数名:int list_size(const list_head_t *head)
* 功能描述:获取以head为表头的列表的大小
* 输入参数:
* head : 列表表头
* 输出参数:
* 无
* 返回值:
* >0 :非空
* 0 :空
***************************************************************************************************/
inline int list_size(const list_head_t *head)
{
int size = 0;
list_head_t *entry = NULL;
if (NULL == head)
{
return 0;
}
list_for_each(entry, head)
{
size++;
}
return size;
}
/***************************************************************************************************
* 函数名:int list_splice_to_head(list_head_t *_new, list_head_t *head)
* 功能描述:把新的列表_new合并到以head为表头的列表的头部
* 输入参数:
* _new : 待合并列表
* head : 原有列表
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_splice_to_head(list_head_t *_new, list_head_t *head)
{
return __list_splice(_new, head, SPLICE_HEAD);
}
/***************************************************************************************************
* 函数名:int list_splice_to_tail(list_head_t *_new, list_head_t *head)
* 功能描述:把新的列表_new合并到以head为表头的列表的尾部
* 输入参数:
* _new : 待合并列表
* head : 原有列表
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_splice_to_tail(list_head_t *_new, list_head_t *head)
{
return __list_splice(_new, head, SPLICE_TAIL);
}
inline int __list_splice(list_head_t *list, list_head_t *head, splice_mode_t mode)
{
list_head_t *first = NULL;
list_head_t *last = NULL;
if (NULL == list || list_is_empty(list) || list_is_empty(head) || SPLICE_UNKNOWN == mode)
{
return -1;
}
first = list->next;
last = list->prev;
if (SPLICE_HEAD == mode)
{
list_head_t *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
else if (SPLICE_TAIL == mode)
{
list_head_t *at = head->prev;
first->prev = at;
at->next = first;
last->next = head;
head->prev = last;
}
return 0;
}
/***************************************************************************************************
* 函数名:int list_replace(list_head_t *_new, list_head_t *old)
* 功能描述:把列表中old节点替换为新的_new节点
* 输入参数:
* _new : 待替换节点
* old : 被替换节点
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_replace(list_head_t *_new, list_head_t *old)
{
if (NULL == _new || NULL == old)
{
return -1;
}
_new->next = old->next;
_new->next->prev = _new;
_new->prev = old->prev;
_new->prev->next = _new;
return 0;
}
/***************************************************************************************************
* 函数名:int list_revese(list_head_t *head)
* 功能描述:把以head为表头的列表中的所有节点前后顺序倒置,倒置后仍然以head为表头
* 输入参数:
* head : 表头
* 输出参数:
* 无
* 返回值:
* 0 :成功
* -1 :失败
***************************************************************************************************/
inline int list_revese(list_head_t *head)
{
list_head_t *first = NULL;
list_head_t *entry = NULL;
if (NULL == head)
{
return -1;
}
if (list_is_empty(head))
{
return -1;
}
first = head->next;
while (head != first->next)
{
entry = first->next;
first->next = entry->next;
entry->next->prev = first;
head->next->prev = entry;
entry->next = head->next;
head->next = entry;
entry->prev = head;
}
return 0;
}