当前位置: 首页 > news >正文

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;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 联影一面面经
  • 探索VB与ASP.NET的融合艺术:Web开发的高效实践
  • Centos7目前能下载到的位置
  • HSE软件组件有哪些?如何实现HSE与主机的通信(同步/异步)?如何使用HSE提供的安全服务?
  • mybatis if标签判断字符串是否相等
  • 【图像去噪】论文精读:Spatial-Adaptive Network for Single Image Denoising(SADNet)
  • 大数据智能风控核心:模型
  • 通过 pnpm 安装依赖包会发生什么
  • Matlab simulink建模与仿真 第三章(连续模块库)
  • 【HarmonyOS NEXT星河版开发实战】灯泡定时开关
  • Unity 图表插件Xcharts的一些坑
  • 【高级IO总结】深度探索高级IO:五种IO模型、高级IO、Select、Poll、Epoll工作模式
  • 信号队列。
  • Ubuntu22.04安装深度学习的GPU环境详细教程(小白图文,显卡驱动、CUDA、cuDNN、PyTorch一步到位)
  • One-Shot Visual Imitation Learning via Meta-Learning
  • Android开源项目规范总结
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • JavaScript实现分页效果
  • js 实现textarea输入字数提示
  • mongodb--安装和初步使用教程
  • Spark RDD学习: aggregate函数
  • spring boot 整合mybatis 无法输出sql的问题
  • springboot_database项目介绍
  • Wamp集成环境 添加PHP的新版本
  • 第2章 网络文档
  • 动手做个聊天室,前端工程师百无聊赖的人生
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 面试题:给你个id,去拿到name,多叉树遍历
  • MPAndroidChart 教程:Y轴 YAxis
  • UI设计初学者应该如何入门?
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • ​虚拟化系列介绍(十)
  • # include “ “ 和 # include < >两者的区别
  • # 达梦数据库知识点
  • # 利刃出鞘_Tomcat 核心原理解析(七)
  • (1)常见O(n^2)排序算法解析
  • (6)设计一个TimeMap
  • (代码示例)使用setTimeout来延迟加载JS脚本文件
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (三)centos7案例实战—vmware虚拟机硬盘挂载与卸载
  • (一)VirtualBox安装增强功能
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)详解PHP处理密码的几种方式
  • .bat文件调用java类的main方法
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .net core 控制台应用程序读取配置文件app.config
  • .NET Core中的去虚
  • .net 发送邮件
  • .NET 设计模式—简单工厂(Simple Factory Pattern)
  • .NET编程——利用C#调用海康机器人工业相机SDK实现回调取图与软触发取图【含免费源码】
  • @PreAuthorize注解
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • @Slf4j idea标红Cannot resolve symbol ‘log‘
  • [ 常用工具篇 ] AntSword 蚁剑安装及使用详解