链表的企业级应用
** 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找出来后,才发觉自己多么的愚蠢…