修復博客: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;
}