Linux 数据结构 内核链表 栈
内核链表:
1.一种链表结构能够操作多种类型的数据对象
2.节点包含数据变成数据包含节点
/*Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>This file is part of GlusterFS.This file is licensed to you under your choice of the GNU LesserGeneral Public License, version 3 or any later version (LGPLv3 orlater), or the GNU General Public License, version 2 (GPLv2), in allcases as published by the Free Software Foundation.
*/#ifndef _LLIST_H
#define _LLIST_H// 定义双向链表结构
struct list_head {struct list_head *next; // 指向链表的下一个节点struct list_head *prev; // 指向链表的上一个节点
};// 初始化链表头
#define INIT_LIST_HEAD(head) do { \(head)->next = (head)->prev = head; \} while (0)// 在链表头后面插入新节点
static inline void
list_add (struct list_head *new, struct list_head *head)
{new->prev = head;new->next = head->next;new->prev->next = new;new->next->prev = new;
}// 在链表尾部插入新节点
static inline void
list_add_tail (struct list_head *new, struct list_head *head)
{new->next = head;new->prev = head->prev;new->prev->next = new;new->next->prev = new;
}// 按顺序插入新节点,根据比较函数的结果决定插入位置
static inline void
list_add_order (struct list_head *new, struct list_head *head,int (*compare)(struct list_head *, struct list_head *))
{struct list_head *pos = head->prev;// 反向遍历链表以找到正确的插入位置while (pos != head) {if (compare(new, pos) >= 0)break;pos = pos->prev;}list_add (new, pos);
}// 从链表中删除节点,并将其指针标记为特殊值
static inline void
list_del (struct list_head *old)
{old->prev->next = old->next;old->next->prev = old->prev;old->next = (void *)0xbabebabe; // 标记已删除节点old->prev = (void *)0xcafecafe; // 标记已删除节点
}// 删除节点并重新初始化节点
static inline void
list_del_init (struct list_head *old)
{old->prev->next = old->next;old->next->prev = old->prev;old->next = old; // 重新初始化节点old->prev = old; // 重新初始化节点
}// 将链表中的某节点移动到链表头部
static inline void
list_move (struct list_head *list, struct list_head *head)
{list_del (list);list_add (list, head);
}// 将链表中的某节点移动到链表尾部
static inline void
list_move_tail (struct list_head *list, struct list_head *head)
{list_del (list);list_add_tail (list, head);
}// 检查链表是否为空
static inline int
list_empty (struct list_head *head)
{return (head->next == head);
}// 将一个链表拼接到另一个链表的头部
static inline void
__list_splice (struct list_head *list, struct list_head *head)
{(list->prev)->next = (head->next);(head->next)->prev = (list->prev);(head)->next = (list->next);(list->next)->prev = (head);
}// 拼接链表到另一个链表头部
static inline void
list_splice (struct list_head *list, struct list_head *head)
{if (list_empty (list))return;__list_splice (list, head);
}// 拼接链表并初始化源链表
static inline void
list_splice_init (struct list_head *list, struct list_head *head)
{if (list_empty (list))return;__list_splice (list, head);INIT_LIST_HEAD (list); // 初始化源链表头
}// 将一个链表拼接到另一个链表的尾部
static inline void
__list_append (struct list_head *list, struct list_head *head)
{(head->prev)->next = (list->next);(list->next)->prev = (head->prev);(head->prev) = (list->prev);(list->prev)->next = head;
}// 拼接链表到另一个链表尾部
static inline void
list_append (struct list_head *list, struct list_head *head)
{if (list_empty (list))return;__list_append (list, head);
}// 拼接链表并初始化源链表
static inline void
list_append_init (struct list_head *list, struct list_head *head)
{if (list_empty (list))return;__list_append (list, head);INIT_LIST_HEAD (list); // 初始化源链表头
}// 判断链表中的某节点是否为最后一个节点
static inline int
list_is_last (struct list_head *list, struct list_head *head)
{return (list->next == head);
}// 判断链表是否只有一个元素
static inline int
list_is_singular(struct list_head *head)
{return !list_empty(head) && (head->next == head->prev);
}// 用新节点替换旧节点
static inline void list_replace(struct list_head *old,struct list_head *new)
{new->next = old->next;new->next->prev = new;new->prev = old->prev;new->prev->next = new;
}// 用新节点替换并初始化旧节点
static inline void list_replace_init(struct list_head *old,struct list_head *new)
{list_replace(old, new);INIT_LIST_HEAD(old); // 重新初始化旧节点
}// 将链表左旋转,将第一个元素移到链表尾部
static inline void list_rotate_left (struct list_head *head)
{struct list_head *first;if (!list_empty (head)) {first = head->next;list_move_tail (first, head); // 将第一个元素移到链表尾部}
}// 获取链表元素结构的指针
#define list_entry(ptr, type, member) \((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))// 获取链表的第一个元素
#define list_first_entry(ptr, type, member) \list_entry((ptr)->next, type, member)// 获取链表的最后一个元素
#define list_last_entry(ptr, type, member) \list_entry((ptr)->prev, type, member)// 获取下一个链表元素
#define list_next_entry(pos, member) \list_entry((pos)->member.next, typeof(*(pos)), member)// 获取上一个链表元素
#define list_prev_entry(pos, member) \list_entry((pos)->member.prev, typeof(*(pos)), member)// 遍历链表
#define list_for_each(pos, head) \for (pos = (head)->next; pos != (head); pos = pos->next)// 遍历链表的每个元素
#define list_for_each_entry(pos, head, member) \for (pos = list_entry((head)->next, typeof(*pos), member); \&pos->member != (head); \pos = list_entry(pos->member.next, typeof(*pos), member))// 安全遍历链表的每个元素
#define list_for_each_entry_safe(pos, n, head, member) \for (pos = list_entry((head)->next, typeof(*pos), member), \n = list_entry(pos->member.next, typeof(*pos), member); \&pos->member != (head); \pos = n, n = list_entry(n->member.next, typeof(*n), member))// 反向遍历链表的每个元素
#define list_for_each_entry_reverse(pos, head, member) \for (pos = list_entry((head)->prev, typeof(*pos), member); \&pos->member != (head); \pos = list_entry(pos->member.prev, typeof(*pos), member))// 安全反向遍历链表的每个元素
#define list_for_each_entry_safe_reverse(pos, n, head, member) \for (pos = list_entry((head)->prev, typeof(*pos), member), \n = list_entry(pos->member.prev, typeof(*pos), member); \&pos->member != (head); \pos = n, n = list_entry(n->member.prev, typeof(*n), member))/** 这个链表实现的优点是简洁、易于理解。它适用于需要快速遍历的简单链表结构,* 但由于使用的是双向链表,它不适用于多指针结构的复杂数据结构。*/
// 获取链表的下一个元素,若到达链表尾则返回NULL
#define list_next(ptr, head, type, member) \(((ptr)->member.next == head) ? NULL \: list_entry((ptr)->member.next, type, member))// 获取链表的上一个元素,若到达链表头则返回NULL
#define list_prev(ptr, head, type, member) \(((ptr)->member.prev == head) ? NULL \: list_entry((ptr)->member.prev, type, member))#endif /* _LLIST_H */
1.栈和队列是特殊的表状结构
表可以在任意位置插入和删除
栈和队列只允许在固定位置插入和删除
2.栈:
FILO
先进后出,后进先出
栈顶:允许入栈出栈的一端称为栈顶
栈底:不允许入栈和出栈的一端称为栈底
入栈(压栈):将数据元素放入栈顶
出栈(弹栈):将数据元素从栈顶位置取出
分类:空增栈
空减栈
满增栈
满减栈
顺序栈(空增栈)
链式栈
#include "seqstack.h"
#include <stdio.h>
#include <stdlib.h>SeqStack *CreateSeqStack(int MaxLen)
{SeqStack *pTmpStack = NULL;//1.申请标签空间pTmpStack = malloc(sizeof(SeqStack));if (NULL == pTmpStack){return NULL;}//2.对每个成员赋初值pTmpStack->tLen = MaxLen;pTmpStack->Top = 0;pTmpStack->pData = malloc(MaxLen * sizeof(DataType));if (NULL == pTmpStack->pData){return NULL;}//3.申请存放数据的空间//4.返回标签地址 return pTmpStack;
}int IsFullSeqStack(SeqStack *pTmpStack)
{return pTmpStack->tLen == pTmpStack->Top ? 1 : 0;
}int IsEmptySeqStack(SeqStack *pTmpStack)
{return 0 == pTmpStack->Top ? 1 : 0;
}int PushSeqStack(SeqStack *pTmpStack, DataType TmpData)
{if (IsFullSeqStack(pTmpStack)){return -1;}pTmpStack->pData[pTmpStack->Top] = TmpData;pTmpStack->Top++;return 0;
}DataType PopSeqStack(SeqStack *pTmpStack)
{if (IsEmptySeqStack(pTmpStack)){return -1;}pTmpStack->Top--;return pTmpStack->pData[pTmpStack->Top];
}int DestroySeqStack(SeqStack **ppTmpStack)
{free((*ppTmpStack)->pData);free(*ppTmpStack);*ppTmpStack = NULL;return 0;
}