引言
链表作为数据结构的基础,其核心在于指针的灵活操作和边界条件的处理。在技术面试和算法竞赛中,链表相关的题目出现频率极高。本文精选了十道经典的链表 OJ 题目,从思路分析到 C 语言代码实现,逐步详解,并穿插了快慢指针、哑结点等常用技巧的讲解。每道题都附带了对应的在线练习参考,方便读者动手实践。
1. 删除链表中等于给定值 val 的所有结点
题目描述
删除链表中所有值为 val 的结点,返回删除后的链表头结点。(参考:力扣 203. 移除链表元素)
思路与实现 创建一个带哨兵位(哑结点)的新链表,将符合条件的节点接到新链表后面,然后返回哨兵位的 next 节点。注意尾节点的 next 需要置为 NULL,如果原链表是空链表,直接返回空链表。
typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
if (head == NULL) return NULL;
ListNode* newhead, *newtail;
newhead = newtail = (ListNode*)malloc(sizeof(ListNode));
ListNode* pcur = head;
while (pcur) {
if (pcur->val != val) {
newtail->next = pcur;
newtail = newtail->next;
}
pcur = pcur->next;
}
newtail->next = NULL;
return newhead->next;
}
2. 反转一个单链表
题目描述 反转一个单链表,返回反转后的链表头结点。(参考:力扣 206. 反转链表)
思路与实现
迭代法是最常用的方式。使用三个指针 prev、curr、next。初始时 prev 为 NULL,curr 指向头结点。每次将 curr->next 指向 prev,然后三个指针整体后移,直到 curr 为 NULL,此时 prev 即为新头结点。
typedef struct ListNode ListNode;
struct ListNode* reverseList( ListNode* head) {
ListNode* n1 = , *n2 = head, *n3 = head ? head->next : ;
(head == ) head;
(n2) {
n2->next = n1;
n1 = n2;
n2 = n3;
(n3) n3 = n3->next;
}
n1;
}


