Linux 数据结构 内核链表 栈

news2024/9/20 20:37:31

内核链表:
    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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2085634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

从雨滴到数据--双翻斗雨量传感器让雨量可视化

CG-04-D1双翻斗雨量传感器是一种重要的水文、气象仪器&#xff0c;主要用于测量自然界中的降雨量&#xff0c;并将降雨量转换为以开关量形式表示的数字信息量输出&#xff0c;以满足信息传输、处理、记录和显示等需求。以下是对双翻斗雨量传感器的详细介绍&#xff1a; 一、工…

手机号码归属地查询如何用PHP进行调用

一、什么是手机号归属地查询接口&#xff1f; 手机号码归属地查询接口又叫手机号归属地、手机号信息查询、手机号查询&#xff0c;通过手机号查询归属地信息、是否虚拟运营商等。该接口可支持三大运营商&#xff0c;移动、电信、联通等。 二、手机号归属地查询接口适用场景有…

《Toolformer: Language Models Can Teach Themselves to Use Tools》论文解读

0. 引言 《Toolformer: Language Models Can Teach Themselves to Use Tools》 论文主要探讨了语言模型&#xff08;LMs&#xff09;在解决新任务时的能力和局限性&#xff0c;并提出了一个名为 Toolformer 的新方法。该方法通过简单 API 接口将外部工具与 LMs 相结合&#xf…

趣味算法------过河卒

目录 ​编辑 题目描述 解题思路 具体代码 总结 问题描述&#xff1a; 解决方案&#xff1a; 代码实现&#xff1a; 关键点&#xff1a; 题目描述 棋盘上 A 点有一个过河卒&#xff0c;需要走到目标 B 点。卒行走的规则&#xff1a;可以向下、或者向右。同时在棋盘上 C…

海外仓系统是什么?你想要了解的都在这里

对从事海外仓经营的人来说&#xff0c;海外仓系统肯定是不陌生的。但是对一些刚进入海外仓领域的货代代理&#xff0c;或一些家庭海外仓的经营者来说&#xff0c;还是有些糊涂&#xff0c;不知道自己到底要不要引入这样的管理系统&#xff0c;引入海外仓系统之后到底能帮自己做…

尚品汇-订单接口实现(四十)

目录&#xff1a; &#xff08;1&#xff09;搭建service-order-client模块 &#xff08;2&#xff09;微服务之间用户信息传递 &#xff08;3&#xff09;在web-all模块中添加接口 &#xff08;4&#xff09;下订单 &#xff08;1&#xff09;搭建service-order-client模…

DDD设计方法-1-初识DDD

前情提要&#xff1a;一共包含 如下六篇文章&#xff08;篇幅精简&#xff0c;快速入门&#xff09; 1、初识DDD 2、聚合、实体、值对象 3、仓储&#xff0c;封装持久化数据 4、端口和适配器 5、领域事件 6、领域服务&#xff0c;实现约定 DDD设计理念-快速入门 DDD&#xff0…

雨水回用一体化设备

雨水回用一体化设备集提升、回用&#xff08;变频恒压供水&#xff09;、排泥系统&#xff1b;絮凝、消毒&#xff08;加药、紫外线&#xff09;、曝气系统&#xff1b;过滤&#xff08;初、精&#xff09;系统&#xff08;全自动自清洗过滤器/石英砂过滤器/多介质过滤器/精密碟…

没错,一分钟告诉你TCP和UDP之间的区别!

TCP (Transmission Control Protocol&#xff09;和UDP (User Datagram Protocol&#xff09;是两种常用的传输层协议&#xff0c;用于在计算机网络中传输数据。 TCP是一种面向连接的协议&#xff0c;提供可靠的数据传输。它通过建立连接、数据分段、流量控制、拥塞控制和错误校…

【论文阅读】skill code 和 one-shot manipulate

文章目录 1. Interpretable Robotic Manipulation from Language针对痛点和贡献摘要和结论引言模型框架实验思考不足之处 2. One-Shot Imitation Learning with Invariance Matching for Robotic Manipulation针对痛点和贡献摘要和结论引言模型框架实验 1. Interpretable Robot…

深入理解快排【C语言版】

目录 一、快排介绍及其思想 二、hoare版本 三、前后指针版 四、挖坑法 五、优化版本 5.1 三数取中 5.2 小区间优化 六 、非递归实现快排 七、三路划分 八、introsort 小结 一、快排介绍及其思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序。它采用了一…

掌握CompletableFuture,提升你的代码效率!

文章目录 1 CompletableFuture与线程池之间有什么关系&#xff1f;2 如何优化CompletableFuture的性能&#xff1f;3 实际项目中&#xff0c;以并行执行多个HTTP请求为例&#xff0c;你会如何优雅使用CompletableFuture 解决问题&#xff1f; 1 CompletableFuture与线程池之间有…

计算机毕业设计选题推荐-在线音乐网站-音乐专辑商城-Java/Python项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

埃隆·马斯克超级计算新里程碑:Cortex AI超级集群震撼亮相!

本周&#xff0c;科技界的超级明星埃隆马斯克再次引领潮流&#xff0c;他在超级计算领域的征途上迈出了令人瞩目的步伐。通过一段视频&#xff0c;他首次公开了最新命名的“Cortex”人工智能超级集群&#xff0c;这一壮举不仅标志着特斯拉“Giga Texas”工厂的又一次重大扩张&a…

LeetCode_sql_day17(1843.可疑银行账户)

描述&#xff1a; 表&#xff1a;Accounts ---------------------- | Column Name | Type | ---------------------- | account_id | int | | max_income | int | ---------------------- account_id 是这张表具有唯一值的列。 每行包含一个银行账户每月最大收入的…

提供开发资料 Hi3516CV610-00B/10B/20B/00S/20S/00G/20G 七个型号配置差异

根据功能不同&#xff0c; Hi3516CV610 分为七个不同型号版本: HI3516CV610-00B HI3516CV610-00B HI3516CV610-10B HI3516CV610-20B HI3516CV610-00S HI3516CV610-20S HI3516CV610-00G HI3516CV610-20G

【书生2.1】书生大模型全链路开源体系

0 引言 书生浦语官网 开源一周年总结及回顾 1 回顾 1.1 社区生态 2 总结 书生浦语大模型的开源开放体系&#xff0c;包括技术发展、性能提升、模型架构、开源生态等。 要点: &#x1f31f; 开源开放体系涵盖数据收集、标注、训练、微调、评测、部署等全链路。 &#x1f68…

【案例64】无法从套接字读取更多的数据

问题现象 系统突然间登录报如下错误&#xff1a;SELECT * FROM sm_user WHERE user_code_q? 无法从套接字读取更多的数据 问题分析 查看nc-log.log发现大量相关报错 $$callid1723104097968-1063 $$thread[http-bio-xxx-xxx-exec-xxx] $$hostxxx$$userid#UAP# $$tsxxx-08-08…

C++竞赛初阶L1-14-第六单元-数组(31~33课)542: T456472 数组逆序重存放

题目内容 将一个数组中的值按逆序重新存放。例如&#xff0c;原来的顺序为 8,6,5,4,1。要求改为 1,4,5,6,8。 输入格式 输入为两行&#xff1a;第一行数组中元素的个数 n&#xff08;1<n≤100)&#xff0c;第二行是 n 个整数&#xff0c;每两个整数之间用空格分隔。 输出…

Windows安装PostgreSQL数据库,保姆级教程

PostgreSQL 是客户端/服务器关系数据库管理系统 (RDMS)。PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统&#xff08;RDBMS&#xff09;。PostgreSQL 也有自己的查询语言&#xff0c;称为 pgsql。 此外&#xff0c;PostgreSQL 还支持过程语言&a…