代码示例
struct hlist_head{
struct hlist_node *first;
};
struct hlist_node{
struct hlist_node * next,**pprev;
};
解读如下:
一、参数
1. struct hlist_head
hlist_head 是链表的头节点,它包含一个指向链表第一个节点的指针 first。
2. struct hlist_node
hlist_node 是链表中的节点结构,它包含两个成员:
- next:指向下一个节点的指针。
- pprev:指向指向当前节点的指针的指针。
二、为什么使用二级指针 (**pprev)?
维护链表结构的灵活性和效率,pprev 是一个指向指针的指针,它指向的是指向当前节点的指针。具体来说,pprev 可以是:
- 如果当前节点是链表中的第一个节点,pprev 就指向 hlist_head 中的 first。
- 如果当前节点不是第一个节点,pprev 就指向前一个节点的 next。
这样设计的好处是,当我们删除或插入节点时,只需要操作一次指针即可,无需遍历链表或更新多个指针。
2.1 插入节点的操作
假设我们要在链表中插入一个新节点 new_node,具体步骤如下:
- 将 new_node->next 设为当前节点 node 的 next。
- 将 new_node->pprev 设为当前节点 node 的 pprev。
- 如果 node->next 不为空,将 node->next->pprev 设为 &new_node->next。
- 将 *node->pprev 设为 new_node。
通过这种方式,可以高效地插入节点而不需要遍历链表。
2.2 删除节点的操作
假设我们要删除一个节点 node,具体步骤如下:
- 如果 node->next 不为空,将 node->next->pprev 设为 node->pprev。
- 将 *node->pprev 设为 node->next。
同样,通过这种方式,可以高效地删除节点而无需遍历链表。
使用二级指针 (**pprev) 可以在不增加复杂度的情况下,简化链表节点的插入和删除操作。这种设计使得链表的操作更加高效,因为每次操作只需要更新一个指针,而不需要遍历整个链表或更新多个指针。
三、图示解析
链表结构图示
假设有一个链表,包含三个节点:node1、node2 和 node3。
1、详细节点指针关系
初始状态
假设初始状态链表中有三个节点 node1、node2 和 node3,指针关系如下:
插入节点
假设我们要在 node2 和 node3 之间插入一个新节点 new_node。
插入前的指针关系:
插入后的步骤:
- 将 new_node->next 设为 node3。
- 将 new_node->pprev 设为 &node2->next。
- 将 node2->next 设为 new_node。
- 将 node3->pprev 设为 &new_node->next。
插入后的指针关系:
删除节点
假设我们要删除 node2
删除前的指针关系:
删除 node2 的步骤:
- 将 node1->next 设为 node2->next(即 node3)。
- 将 node3->pprev 设为 node2->pprev(即 &node1->next)。
删除后的指针关系:
通过这两个操作示例,可以看出使用二级指针 (**pprev) 的好处,在插入和删除节点时不需要遍历链表,只需更新相关的指针即可。