Intrusive Linked List

侵入式链表

将链表的指针域放在数据结构中,而不是在链表节点中

适用于一个数据结构需要在多个链表中存在的情况

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct ListNode {
ListNode *next;
explicit ListNode() : next(nullptr) {}
};

template <class T> struct Node {
T val;
ListNode node;

explicit Node(T val) : val(val) {}
};

template <class T> struct List {
ListNode *head;

List() : head(nullptr) {}

void push_front(T val) {
Node<T> *node = new Node<T>(val);
node->node.next = head;
head = &node->node;
}
};

变量使用 C 语言的宏定义,可以通过 struct 的成员变量指针获取到结构体的地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#define list_entry(type, member, ptr) container_of(type, member, ptr)

#define container_of(type, member, ptr) \
({ \
const typeof(((type *)0)->member) *__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type, member)); \
})

#define offsetof(type, member) ((size_t) & ((type *)0)->member)

int main() {
List<int> list = List<int>();
for (int i = 0; i < 10; i++) {
list.push_front(i);
}
auto *head = list.head;
while (head != nullptr) {
std::cout << list_entry(Node<int>, node, head)->val << std::endl;
head = head->next;
}
return 0;
}

trick

在 C 语言的宏定义中,({}) 是 GNU C 扩展中的一种语法,称为 语句表达式(Statement Expressions)。允许在宏或代码中使用多个语句,并返回最后一行的一个值(使用这种语法最后一行需要加上;,如果只使用 {},也可以返回最后一行的值,同时不用加上;

下面两种写法都是合法的

1
2
int a = {1};
int b = ({1;});

Intrusive Linked List
https://hanzhang-xyz.github.io/2024/10/10/Intrusive-Linked-List/
Author
Han Zhang
Posted on
October 10, 2024
Licensed under