内核链表:
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 Lesser
General Public License, version 3 or any later version (LGPLv3 or
later), or the GNU General Public License, version 2 (GPLv2), in all
cases 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;
}