“链表按索引插入”在业界用的多吗?

在开源项目中(如 Linux Kernel, Redis, GNOME GLib 等)

1. 极少使用“按索引插入” (Insert at Index)

在高性能 C 编程中,链表主要用于 O(1)O(1)O(1) 的头插、尾插或特定节点前后的插入
如果你频繁需要“在第 iii 个位置插入”,说明你选错了数据结构——这种场景应该使用 数组 (Array)动态数组 (Vector)。链表的“按索引访问”是 O(N)O(N)O(N) 的,效率极低。

因此,很多开源库甚至不提供 insert_at_index(i) 这种 API。

2. Linux Kernel (list.h)

Linux 内核使用的是双向循环链表,它的设计极其精简,不存储长度

  • 越界判断: 它没有“越界”的概念,因为它的 API 是 list_add(new, head)(插到头)或 list_add(new, prev_node)(插到某节点后)。
  • 设计哲学: 这里的假设是调用者已经持有了一个有效的节点指针。
3. Redis (adlist.c)

Redis 实现了一个通用的双向链表,它的结构体明确包含了长度

// Redis 的 list 定义
typedef struct list {
    listNode *head;
    listNode *tail;
    unsigned long len; // <--- 这里保存了长度
    // ... 函数指针等 ...
} list;
  • 做法: Redis 确实维护了长度。
  • 但注意: 即使有了 len,Redis 的核心 API 依然主要是 listAddNodeHeadlistAddNodeTail。如果它要实现 Index 操作(如 listIndex 获取节点),它会利用 len 来决定是从头遍历更快还是从尾遍历更快(优化),但插入操作依然很少基于索引。

4. 总结建议

  1. 如果是刷题/简单练习: 不要维护 length。在遍历寻找插入点的 while 循环中判断 p 是否为 NULL,以此作为越界判断。
  2. 如果是工程项目: 建议定义一个 struct List { Node* head; int len; }
    • 这样你可以在开头判断 i > len
    • 这能让调用者快速获取链表长度(O(1)),非常实用。

只有当你将链表长度缓存在结构体中时,才能在函数开头判断越界。否则,必须通过遍历来检测。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值