Liunx内核 “共享” 双向链表

链表的企业级应用

** Linux内核“共享”双向链表**

有没有一种方式,可以让多个链表共享同一套链表的操作?欣赏如下图片
在这里插入图片描述

相同的车, 拉的东西却不同, 那么有没有办法实现一套共享的链表呢? 答案肯定是有的,机器是死的,人是活的, 这个道理永远都是真理…

共享链表的元素就是把双向链表中的指针域和数据域分开, 让指针域作为数据域中的一个“挂件”
如下图:

在这里插入图片描述

实现要点:
使用 offsetof 可以根据链表节点在结构体中的地址逆推出结构体变量的位置, offsetof是一个宏

#include <iostream>
#include <Windows.h>
#include <stdio.h>

//共享链表的定义
typedef struct _DLinkList {
	struct _DLinkList* next;
	struct _DLinkList* prev;
}DLinkList, DLinkNode;


// 比如这里的数据如下
typedef struct _Elem {
	int x;
	int y;
	char a[16];
	DLinkList node;		//双向链表作为 数据的挂件
}Elem;


// 初始化
void init(DLinkList& dl) {
	dl.next = NULL;
	dl.prev = NULL;
}

// 前插法
void insertFront(DLinkList& dl, DLinkNode& node) {
	node.next = dl.next;
	node.prev = &dl;
	
	if(dl.next) dl.next->prev = &node;
	dl.next = &node;

}

// 尾插法
void insertBack(DLinkList& dl, DLinkNode& node) {
	DLinkNode* last = &dl;
	while(last->next) last = last->next;

	node.next = last->next;
	node.prev = last;
	last->next = &node;
}

// 遍历
void print(DLinkNode& dl) {
	if(!dl.next) return;
	int offset;
	DLinkNode* last = dl.next;
	Elem* p = NULL;
	offset = offsetof(Elem, node);
	while(last) {
		p = (Elem*)((size_t)last - offset);
		printf("x = %d, y = %d, a = %s", p->x, p->y, p->a);
		last = last->next;
	}
	printf("\n");
}

//链表的删除节点
void DLinkDelete(DLinkList& dl, const int i) {
	if(!dl.next) return;	//不存在节点
	if(i < 1) return ;	//删除不合理
	
 	int offset;
	 DLinkNode* last = dl.next;
	int count  = 1;
	
	 Elem* p = NULL;
	 offset = offsetof(Elem, node);

	while(last && count < i) {
		last = last->next;
		count++;
	}

	if(!last) return ;
	
	last->prev->next = last->next;
	if(last->next) last->next->prev = last->prev;
	
	// 找到要删除的节点地址
	p = (Elem*)((size_t)last - offset);
	delete p;
}

// 链表的销毁
void DLinkDestroy(DLinkList& dl) {
	DLinkNode* p = dl.next;
	Elem* temp = NULL;
	int offset = offsetof(Elem, node);

	while(p) {
		temp = (Elem*)((size_t)p - offset);
		p = p->next;
	}
	dl.next = NULL;
	dl.prev = NULL;
}

int main(void) {
	Elem head;	//头节点
	Elem *e = NULL;		//插入节点
	int n = 0;
	
	// 初始化双向链表
	init(head.node);
	// 根据数据里有什么数据实现相应的操作
	printf("请输入前插法插入的元素数量: ");
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		e = new Elem;
		if(!e) exit(1);
	
		printf("请输入x的值:");
		scanf("%d", &e->x);
		printf("请输入y的值:");
		scanf("%d", &e->y);
		printf("输入相关信息:");
		scanf("%s", e->a);
		 // 前插法
		insertFront(head.node, e->node);
	}
	// 打印
	print(head.node);

	printf("请输入尾插法插入的元素数量:");
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		  e = new Elem;
		  if(!e) exit(1);
 
		  printf("请输入x的值:");
		  scanf("%d", &e->x);
		  printf("请输入y的值:");
		  scanf("%d", &e->y);
		  printf("输入相关信息:");
		  scanf("%s", e->a);
		   // 尾插法
		  insertBack(head.node, e->node);
	 }

	print(head.node);

	system("pause");
	return 0;
}

这篇博客写的本人写的有点崩溃,我也刚开始接触数据结构,第一次写这样的代码,感觉泪崩,bug不断,一天写一点,不断调试,终于是写出来,至于有没有问题就不知道了…

在这里感觉小五郎 云 Martin老师…没有他们的帮助,这个应该还需要晚一点才能写出来, 其中有一个bug让我印象深刻… 代码里的head 是局部变量,不是动态分配的, 而我却释放它, 这个bug找了很久,在他们的帮助下,终于是找到了, 一直我都在觉得是代码哪里不对,可是怎么看,怎么对,直到bug找出来后,才发觉自己多么的愚蠢…

发布了18 篇原创文章 · 获赞 2 · 访问量 226

猜你喜欢

转载自blog.csdn.net/weixin_44238530/article/details/102631458