说明

共享双链表意义在于,可以用一套函数维护不同数据类型的双链表

准备

定义双链表

#include <iostream>
#include <string> using namespace std; //此处并不包含数据域,仅有指针域用于连接结点
typedef struct _DbLinkList
{
struct _DbLinkList *next;
struct _DbLinkList *prev;
}DbLinkList;

定义结构体

//定义数据类型,并挂载双链表的指针
struct num
{
int data;
DbLinkList node; //此处不用指针,以保证在为该结构体分配内存时同时为双链表分配
}; struct str
{
string data;
DbLinkList node; //此处不用指针,以保证在为该结构体分配内存时同时为双链表分配
};

操作

初始化

//因为在保存数据的结构体中未用双链表的指针,所以此处L使用引用而非引用类型的指针
bool initList(DbLinkList &L)
{
L.next = NULL;
L.prev = NULL;
return true;
}

尾插法

bool insertBack(DbLinkList &L, DbLinkList &node)
{
DbLinkList *p = &L; while(p->next) p = p->next; node.next = NULL;
p->next = &node;
node.prev = p; return true;
}

实际操作

对于struct num

main函数

int main()
{ num *N = new num;
N->data = -1; initList(N->node); //尾插法
num *n = new num;
n->data = 2;
insertBack(N->node, n->node); //用链表访问结点的数据
DbLinkList *p = &(N->node);
while(p)
{
//获取在结构体中node距离结构体顶点的距离
int offset = offsetof(num, node);
/*
* data地址 = 结构体底地址 - node距离结构体顶点的距离
* 但指针不能直接加减,所以要先转化为size_t类型,得到结果后再转为指针类型
*/
num *tmp = (num *)((size_t)p - offset);
cout << "NUM:" << tmp->data << endl;
p = p->next;
} return 0;
}

输出结果

NUM:-1
NUM:2

对于struct str

同理

main函数

int main()
{
str *S = new str;
S->data = "hello,world"; initList(S->node); //尾插法
str *s = new str;
s->data = "你好,世界";
insertBack(S->node, s->node); //用链表访问结点的数据
DbLinkList *p = &(S->node);
while(p)
{
//获取在结构体中node距离结构体顶点的距离
int offset = offsetof(str, node);
/*
* data地址 = 结构体底地址 - node距离结构体顶点的距离
* 但指针不能直接加减,所以要先转化为size_t类型,得到结果后再转为指针类型
*/
str *tmp = (str *)((size_t)p - offset);
cout << "STR:" << tmp->data << endl;
p = p->next;
} return 0;
}

输出结果

STR:hello,world
STR:你好,世界

(注意:本文没有做双链表的销毁操作,虽然程序可以正常运行但这样做是不可取的)

思考

能不能将不同类型的结构体都放在一个双链表上?

如果能该怎么读取数据?

Linux内核链表之共享双链表的更多相关文章

  1. Linux 底下使用C语言的 单链表 ,双链表,二叉树 读取文件,并排序

    直接上代码 单链表Linux读文件排序: 双链表Linux读取文件排序: 二叉树LinuX读取文件并排序:

  2. linux内核里的字符串转换 ,链表操作常用函数(转)

    1.对双向链表的具体操作如下: list_add ———向链表添加一个条目 list_add_tail ———添加一个条目到链表尾部 __list_del_entry ———从链表中删除相应的条目 l ...

  3. Python与数据结构[0] -> 链表/LinkedList[1] -> 双链表与循环双链表的 Python 实现

    双链表 / Doubly Linked List 目录 双链表 循环双链表 1 双链表 双链表和单链表的不同之处在于,双链表需要多增加一个域(C语言),即在Python中需要多增加一个属性,用于存储指 ...

  4. 深入分析 Linux 内核链表--转

    引用地址:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 一. 链表数据结构简介 链表是一种常用的组织有序数据 ...

  5. 深入分析 Linux 内核链表

    转载:http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/   一. 链表数据结构简介 链表是一种常用的组织有序数据的数据结构,它通过指 ...

  6. Linux内核中链表实现

    关于双链表实现,一般教科书上定义一个双向链表节点的方法如下: struct list_node{ stuct list_node *pre; stuct list_node *next; ElemTy ...

  7. Linux 内核链表的使用及深入分析【转】

    转自:http://blog.csdn.net/BoArmy/article/details/8652776 1.内核链表和普通链表的区别 内核链表是一个双向链表,但是与普通的双向链表又有所区别.内核 ...

  8. linux 内核的链表操作(好文不得不转)

    以下全部来自于http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 无任何个人意见. 本文详细分析了 2.6.x 内 ...

  9. 数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现

    概要 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列.本章先介绍线性表的几个基本组成部分:数组.单向链表.双向链表:随后给出双向链表的C.C++和Java三种语言的实现. ...

随机推荐

  1. 原生 JS 实现 VS Code 自动切换输入法状态!这次没有AHK

    上一篇文章:使用 AHK 在 VS Code 中根据上下文自动切换输入法状态 给出一个使用 ahk 在 VSCode 自动切换输入法的方法.不过这个方法实际上很蹩脚,一点都不优(zhuang)雅(bi ...

  2. Qt记事本,美化版

    主体代码实现 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QMenu> ...

  3. 对 Kubernetes 部署进行故障排除的视觉指南

    链接:https://learnk8s.io/troubleshooting-deployments

  4. Kubernetes 使用kubeadm创建集群

    镜像下载.域名解析.时间同步请点击 阿里巴巴开源镜像站 实践环境 CentOS-7-x86_64-DVD-1810 Docker 19.03.9 Kubernetes version: v1.20.5 ...

  5. 模型 _meta API ( options )

    模型 _meta API class Options[源代码] 模型 _meta API是Django ORM的核心.它使系统的其他部分(如查找,查询,表单和管理员)能够了解每个模型的功能. API可 ...

  6. 内网渗透----Token 窃取与利用

    0x00 前言 在之前的文章<渗透技巧--程序的降权启动>介绍了使用 SelectMyParent 降权的方法,本质上是通过 token 窃取实现的.这一次将要对 token 窃取和利用做 ...

  7. C++ 并发编程2 --向线程函数传递参数

    1向线程函数传递参数比较简单,一般的形式如下 void f(int i,std::string const& s);std::thread t(f,3, "hello"); ...

  8. Ubuntu修改登录密码

    Ubuntu 修改用户名或密码后无法登陆 解决方法 2017年09月01日 16:48:05 lee_3312 阅读数:2192   解决方法:进入recovery-mode修改登录信息 1)重启系统 ...

  9. Jakarta Java Mail属性参数配置

    前言 Jakarta Mail网址:https://eclipse-ee4j.github.io/mail SMTP协议可匹配的属性:https://eclipse-ee4j.github.io/ma ...

  10. JDBC 中如何进行事务处理?

    Connection 提供了事务处理的方法,通过调用 setAutoCommit(false)可以设置 手动提交事务:当事务完成后用 commit()显式提交事务:如果在事务处理过程中 发生异常则通过 ...