单链表/双链表/循环链表
1. 单链表
总概述
1.1 尾插
1.2 头插
1.3 尾删
法一:
法二:
1.4 头删
1.5 查找
1.6 某个节点前插入
1.7 删除某个节点
1.8 某个节点后面插入
1.9 删除某个节点后一个节点
1.10 销毁
1.11 测试和头文件
头文件
测试
1.11 OJ题【调试技巧】
1.11.1 题目一
203. 移除链表元素 - 力扣(LeetCode)
遍历链表,当发现不是要找的那个元素就直接拷贝到新的链表里面,如果是要删的元素,就直接在原链表里面跳过并且释放,不用拷贝到新的链表里面
调试技巧:快速手搓链表
struct ListNode* n1 = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* n2 = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* n3 = (struct ListNode*)malloc(sizeof(struct ListNode));
struct ListNode* n4 = (struct ListNode*)malloc(sizeof(struct ListNode));
n1->val = 1;
n2->val = 1;
n3->val = 2;
n4->val = 1;
n1->next = n2;
n2->next = n3;
n3->next = n4;
n4->next = NULL;
1.11.2 题目二
876. 链表的中间结点 - 力扣(LeetCode)
采用时间速度上的快慢指针的方式,快指针一次走2个结点,慢指针一次走1个结点
1.11.3 题目三
链表中倒数最后k个结点_牛客题霸_牛客网
采用空间上的快慢指针
1.11.4 题目四
LCR 024. 反转链表 - 力扣(LeetCode)
先画图,再写代码,最后调试!
三指针
法二:头插到新链表(推荐)
1.11.5 题目五
21. 合并两个有序链表 - 力扣(LeetCode)
谁小就取谁尾插,尾插可以考虑用带哨兵位的头节点
1.11.6 题目六
面试题 02.04. 分割链表 - 力扣(LeetCode)
小于尾插到一个链表,大于等于尾插到另一个链表,然后再链接起来
1.11.7 题目七
LCR 027. 回文链表 - 力扣(LeetCode)
利用快慢指针找到中间节点,从中间结点开始对后半段逆置,前半段和后半段比较
1.11.8 题目八
LCR 023. 相交链表 - 力扣(LeetCode)
分别求两个链表的长度,让长的链表先走差距步,同时走第一个地址相同就是交点
1.11.9 题目九
141. 环形链表 - 力扣(LeetCode)
1.11.10 题目十
LCR 022. 环形链表 II - 力扣(LeetCode)
方法一:
一个指针从起始点出发,另一个指针从相遇点出发,他们会在入口点相遇!
方法二:
将相遇点和它的下一个结点断开,转换成求交点问题
2.带哨兵位的双向循环链表
2.1 创建结点
2.2 初始化
2.3 销毁
2.4 打印
2.5 尾插
2.6 尾删
2.7 判空
2.8 头插
2.9 头删
2.10 pos前插入
2.11 删除pos指向的结点
2.12 查找x
2.13 头文件和测试
2.14 OJ题
LCR 154. 复杂链表的复制 - 力扣(LeetCode)
每个拷贝结点都链接在原结点的后面
拷贝结点的random是原结点的random->next
拷贝结点接下来,链接成新链表,并且恢复原链表
3.链表和顺序表的区别
推荐书籍:较难