一种通用链表设计

本文介绍了如何使用C语言设计一个通用的双向链表结构,重点讲解了CONTAINER_OF宏的实现原理及其在链表操作中的应用。通过具体的IntNode测试案例,展示了头插、遍历和删除等操作,探讨了C和C++在链表实现上的差异,并推荐了相关主题的阅读材料。
摘要由CSDN通过智能技术生成

内容简介

最近在看一个开源库的代码,用 C 实现了一种通用的双向链表结构。设计思想是将prevnext抽取成struct Node,针对Node编写通用的双向链表类。当需构造特定类型的链表时,首先在其中定义一个Node类型的成员,然后使用CONTAINER_OF宏借助Node的成员的关系得到特定类型链表关系,无需再为特定类型链表编写专用函数。

本文以IntNode为例,演示通用Node双向链表类和CONTAINER_OF宏的使用。其实,写这篇文章就是为了介绍CONTAINER_OF这个宏。

设计实现

Node 节实现

struct Node {
   
    Node *prev;
    Node *next;
};

通用的双向链表类实现

本文的重点不在于双向链表,直接附上一种双向循环链表XList的实现。技巧点在于利用一个常驻Node节点作为head,简化代码。基础的数据结构没事可以看看,磨磨脑子。其实开源库中代码的XList也是宏定义,没啥亮点,为了提高可读性,直接使用 C++的class实现。

XList 构造和析构

XList::XList() {
   
    head_ = x_new(Node); // 常驻头结点
    head_->next = head_;
    head_->prev = head_;
    size_ = 0; // 链表初始大小
}

XList::~XList() {
   
    x_delete(head_);
    head_ = nullptr;
}

XList 头插和尾插

void XList::PushFront(Node *node) {
   
    node->prev = head_;
    node->next = head_->next;
    head_->next->prev = node;
    head_->next = node;
    ++size_;
}

void XList::PushBack(Node *node) {
   
    node->prev = head_->prev;
    node->next
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Pintos是一个操作系统的教学项目,它里面有许多基础的数据结构。其中之一就是通用链表(generic list)。 链表是一个常见的数据结构,用于存储一系列的元素。在Pintos中,通用链表一种灵活且可扩展的数据结构,可以存储任意类型的元素。 Pintos中的通用链表由两个主要的结构组成:链表节点和链表本身。每个链表节点包含了一个指向前一个节点的指针和一个指向后一个节点的指针,以及一个用于存储元素的指针。链表本身则包含了一个指向头节点和尾节点的指针,以及用于记录链表长度的变量。 通过使用这些结构,Pintos的通用链表提供了一系列的操作来管理链表中的元素。比如,它可以实现在链表头部和尾部插入元素、删除元素以及在指定位置插入或删除元素等功能。此外,通过遍历链表,我们可以对链表中的每个元素进行操作,比如查找、更新和打印。 Pintos的通用链表使用简单而高效的方法来处理链表操作。通过使用指针连接节点,我们可以轻松地插入和删除元素,并且时间复杂度为O(1)。而遍历链表的操作也只需要O(n)的时间复杂度,其中n是链表的长度。 总之,Pintos的通用链表为操作系统的开发提供了一个方便和高效的数据结构。它可以存储任意类型的元素,并提供了丰富的操作来管理和操作这些元素。无论是在Pintos项目中还是在实际操作系统的开发中,通用链表都是一个非常有用的工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值