
🏰 第一章:什么是链表?
🎯 故事开场
在一个叫"数据王国"的地方,有两种排队方式:
🍬 队伍1:数组村
小朋友们手拉手站好,位置固定:
[小A][小B][小C][小D]
👉 想插队?必须整体挪动!
🚂 队伍2:链表火车(今天主角!)
每个小朋友坐一节车厢,只知道"下一节是谁":
小A → 小B → 小C → 小D
👉 插入?直接接上去!
👉 删除?跳过去就行!
🧠 第二章:链表的结构(最重要!)
🎯 单链表节点长这样:
struct Node
{
int data; // 数据(小朋友的名字)
Node* next; // 指向下一个人
};
👉 每个节点 = 数据 + 指针(指路牌)
🏗 第三章:创建链表(搭火车!)
🎯 故事:建一列火车
Node* head = NULL; // 火车头(空)
// 创建第一个节点
Node* a = new Node{1, NULL};
head = a;
// 创建第二个节点
Node* b = new Node{2, NULL};
a->next = b;
// 创建第三个节点
Node* c = new Node{3, NULL};
b->next = c;
🚂 结果:
1 → 2 → 3 → NULL
🔍 第四章:遍历链表(参观火车)
🎯 故事:列车员检查每一节车厢
Node* p = head;
while(p != NULL)
{
cout << p->data << " ";
p = p->next;
}
👉 输出:
1 2 3
➕ 第五章:插入节点(新车厢加入)
🎯 1️⃣ 头部插入(插队第一名)
Node* newNode = new Node{0, head};
head = newNode;
🚂:
0 → 1 → 2 → 3
🎯 2️⃣ 中间插入
👉 在 2 后面插入 99
Node* p = head;
while(p->data != 2)
{
p = p->next;
}
Node* newNode = new Node{99, p->next};
p->next = newNode;
🚂:
1 → 2 → 99 → 3
❌ 第六章:删除节点(车厢拆除)
🎯 删除值为2的节点
Node* p = head;
while(p->next != NULL && p->next->data != 2)
{
p = p->next;
}
Node* temp = p->next;
p->next = temp->next;
delete temp;
🚂:
1 → 3
🔄 第七章:链表反转(火车掉头!)
🎯 故事:整列火车调头!
原来:
1 → 2 → 3
变成:
3 → 2 → 1
🧠 核心思路(三指针)
Node* prev = NULL;
Node* cur = head;
while(cur != NULL)
{
Node* next = cur->next; // 保存下一节
cur->next = prev; // 反向
prev = cur; // 前进
cur = next;
}
head = prev;
🔁 第八章:🌟用输入创建链表🌟
1、刚才我们是这样建火车的:
Node* a = new Node{1, NULL};
Node* b = new Node{2, NULL};
Node* c = new Node{3, NULL};
👉 ❌ 问题:
数据是写死的
不能让用户输入
不符合考试要求
2、目标
👉 用户输入:
输入:
5
1 2 3 4 5
👉 我们要创建:
1 → 2 → 3 → 4 → 5 → NULL
3、🎯 方法:尾插法(最常用🔥)
👉 一边读输入,一边接到链表后面!
🚂 图解过程
假设输入:1 2 3
第1步:插入1
1 → NULL
第2步:插入2
1 → 2 → NULL
第3步:插入3
1 → 2 → 3 → NULL
4、🚀 使用 tail(推荐🔥🔥🔥)
(1)💡 核心思想
👉 用一个指针记住"尾巴"
(2)💻 完整代码
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
int main()
{
int n;
cin >> n;
Node* head = NULL;
Node* tail = NULL;
for(int i = 0; i < n; i++)
{
int x;
cin >> x;
Node* node = new Node{x, NULL};
if(head == NULL)
{
head = tail = node;
}
else
{
tail->next = node;
tail = node;
}
}
// 输出
Node* p = head;
while(p)
{
cout << p->data << " ";
p = p->next;
}
return 0;
}
5、🎁 进阶写法(封装函数)
cpp
Node* buildList(int n)
{
Node* head = NULL;
Node* tail = NULL;
for(int i = 0; i < n; i++)
{
int x;
cin >> x;
Node* node = new Node{x, NULL};
if(head == NULL)
head = tail = node;
else
{
tail->next = node;
tail = node;
}
}
return head;
}
6、🎯 三种建链方式
1️⃣ 手写节点(学习用)
2️⃣ insertTail(基础用)
3️⃣ tail优化(考试用🔥)
🧪 第九章:完整参考代码
cpp
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Node* buildList(int n) {
Node* head = NULL;
Node* tail = NULL;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
Node* node = new Node{x, NULL};
if (head == NULL)
head = tail = node;
else {
tail->next = node;
tail = node;
}
}
return head;
}
void printList(Node* head) {
Node* p = head;
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
Node* reverseList(Node* head) {
Node* prev = NULL;
Node* cur = head;
while (cur != NULL) {
Node* next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
return prev;
}
int main() {
int n;
cout << "请输入链表长度: ";
cin >> n;
cout << "请输入链表元素(共" << n << "个): ";
Node* list = buildList(n);
cout << "原链表: ";
printList(list);
Node* reversed = reverseList(list);
cout << "反转后链表: ";
printList(reversed);
return 0;
}
🎯 第十章:总结口诀
✨ 链表口诀:
创建节点两部分:数据 + 指针
遍历链表用 while,走到 NULL 停下来
插入节点改指针,新旧连接要记清
删除节点先保存,再断开来再释放
链表反转三指针,prev cur next要分明
我们继续进入升级冒险------
🌟《链表10道经典练习题》🌟
目标:让你 真正会写、会用、会做题!
🧩 第1题:打印链表(最基础)
1、🎯 故事
你是"火车检票员",要检查每节车厢的编号。
2、🚂 图解
1 → 2 → 3 → 4
3、💡 思路
从头走到尾,每个都打印。
4、💻 核心代码
void printList(Node* head)
{
Node* p = head;
while(p != NULL)
{
cout << p->data << " ";
p = p->next;
}
}
5、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
void printList(Node* head)
{
Node* p = head;
while(p != NULL)
{
cout << p->data << " ";
p = p->next;
}
}
int main()
{
// 创建链表 1→2→3→4
Node* a = new Node{1, NULL};
Node* b = new Node{2, NULL};
Node* c = new Node{3, NULL};
Node* d = new Node{4, NULL};
a->next = b;
b->next = c;
c->next = d;
Node* head = a;
printList(head);
return 0;
}
🧩 第2题:统计节点个数
1、🎯 故事
数一数火车有几节车厢 🚃
2、💡 思路
遍历 + 计数器
3、💻核心代码
int count(Node* head)
{
int cnt = 0;
while(head)
{
cnt++;
head = head->next;
}
return cnt;
}
4、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
int count(Node* head)
{
int cnt = 0;
while(head)
{
cnt++;
head = head->next;
}
return cnt;
}
int main()
{
Node* a = new Node{1, NULL};
Node* b = new Node{2, NULL};
Node* c = new Node{3, NULL};
a->next = b;
b->next = c;
cout << count(a);
return 0;
}
🧩 第3题:查找某个值
1、🎯 故事
找"3号乘客"在哪里?
2、💻核心代码
bool find(Node* head, int x)
{
while(head)
{
if(head->data == x) return true;
head = head->next;
}
return false;
}
3、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
bool find(Node* head, int x)
{
while(head)
{
if(head->data == x) return true;
head = head->next;
}
return false;
}
int main()
{
Node* a = new Node{1, NULL};
Node* b = new Node{2, NULL};
Node* c = new Node{3, NULL};
a->next = b;
b->next = c;
cout << find(a, 3); // 1 表示找到
return 0;
}
🧩 第4题:头插法建链表
1、🎯 故事
每次新乘客都插队到最前面 😄
2、💻核心代码
Node* insertHead(Node* head, int x)
{
return new Node{x, head};
}
3、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* insertHead(Node* head, int x)
{
return new Node{x, head};
}
void print(Node* head)
{
while(head)
{
cout << head->data << " ";
head = head->next;
}
}
int main()
{
Node* head = NULL;
head = insertHead(head, 3);
head = insertHead(head, 2);
head = insertHead(head, 1);
print(head); // 1 2 3
return 0;
}
🧩 第5题:尾插法建链表
1、🎯 故事
乘客排队上车,按顺序来
2、🚂 图解
1 → 2 → 3
3、💻核心代码
Node* insertTail(Node* head, int x)
{
Node* node = new Node{x, NULL};
if(head == NULL) return node;
Node* p = head;
while(p->next != NULL)
p = p->next;
p->next = node;
return head;
}
4、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* insertTail(Node* head, int x)
{
Node* node = new Node{x, NULL};
if(head == NULL) return node;
Node* p = head;
while(p->next)
p = p->next;
p->next = node;
return head;
}
void print(Node* head)
{
while(head)
{
cout << head->data << " ";
head = head->next;
}
}
int main()
{
Node* head = NULL;
head = insertTail(head, 1);
head = insertTail(head, 2);
head = insertTail(head, 3);
print(head);
return 0;
}
🧩 第6题:删除第一个等于x的节点
1、🎯 故事
把"捣乱的乘客x"请下车 🚫
2、💻核心代码
Node* deleteValue(Node* head, int x)
{
if(head == NULL) return head;
if(head->data == x)
{
Node* t = head;
head = head->next;
delete t;
return head;
}
Node* p = head;
while(p->next && p->next->data != x)
p = p->next;
if(p->next)
{
Node* t = p->next;
p->next = t->next;
delete t;
}
return head;
}
3、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* deleteValue(Node* head, int x)
{
if(head == NULL) return head;
if(head->data == x)
{
Node* t = head;
head = head->next;
delete t;
return head;
}
Node* p = head;
while(p->next && p->next->data != x)
p = p->next;
if(p->next)
{
Node* t = p->next;
p->next = t->next;
delete t;
}
return head;
}
void print(Node* head)
{
while(head)
{
cout << head->data << " ";
head = head->next;
}
}
int main()
{
Node* head = new Node{1, new Node{2, new Node{3, NULL}}};
head = deleteValue(head, 2);
print(head); // 1 3
return 0;
}
🧩 第7题:反转链表
1、🎯 故事
火车全部掉头!
2、💻核心代码
Node* reverse(Node* head)
{
Node* prev = NULL;
Node* cur = head;
while(cur)
{
Node* next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
return prev;
}
3、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* reverse(Node* head)
{
Node* prev = NULL;
Node* cur = head;
while(cur)
{
Node* next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
return prev;
}
void print(Node* head)
{
while(head)
{
cout << head->data << " ";
head = head->next;
}
}
int main()
{
Node* head = new Node{1, new Node{2, new Node{3, NULL}}};
head = reverse(head);
print(head); // 3 2 1
return 0;
}
🧩 第8题:找中间节点(快慢指针)
1、🎯 故事
一个人走一步,一个人走两步 👣
2、💻核心代码
Node* middle(Node* head)
{
Node* slow = head;
Node* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
3、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* middle(Node* head)
{
Node* slow = head;
Node* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
int main()
{
Node* head = new Node{1, new Node{2, new Node{3, new Node{4, NULL}}}};
Node* mid = middle(head);
cout << mid->data; // 3
return 0;
}
🧩 第9题:判断链表是否有环(进阶🔥)
1、🎯 故事
火车是不是绕圈了?
2、💻核心代码
bool hasCycle(Node* head)
{
Node* slow = head;
Node* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}
3、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
bool hasCycle(Node* head)
{
Node* slow = head;
Node* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}
int main()
{
Node* a = new Node{1, NULL};
Node* b = new Node{2, NULL};
Node* c = new Node{3, NULL};
a->next = b;
b->next = c;
c->next = a; // 制造环
cout << hasCycle(a); // 1
return 0;
}
🧩 第10题:合并两个有序链表(进阶🔥🔥)
1、🎯 故事
两列有序火车合并成一列 🚄🚄
1→3→5
2→4→6
👉 变成:
1→2→3→4→5→6
2、💻核心代码
Node* merge(Node* a, Node* b)
{
Node dummy;
Node* tail = &dummy;
dummy.next = NULL;
while(a && b)
{
if(a->data < b->data)
{
tail->next = a;
a = a->next;
}
else
{
tail->next = b;
b = b->next;
}
tail = tail->next;
}
if(a) tail->next = a;
if(b) tail->next = b;
return dummy.next;
}
3、💻 参考程序
cpp
#include <iostream>
using namespace std;
struct Node
{
int data;
Node* next;
};
Node* merge(Node* a, Node* b)
{
Node dummy;
Node* tail = &dummy;
dummy.next = NULL;
while(a && b)
{
if(a->data < b->data)
{
tail->next = a;
a = a->next;
}
else
{
tail->next = b;
b = b->next;
}
tail = tail->next;
}
if(a) tail->next = a;
if(b) tail->next = b;
return dummy.next;
}
void print(Node* head)
{
while(head)
{
cout << head->data << " ";
head = head->next;
}
}
int main()
{
Node* a = new Node{1, new Node{3, new Node{5, NULL}}};
Node* b = new Node{2, new Node{4, new Node{6, NULL}}};
Node* c = merge(a, b);
print(c); // 1 2 3 4 5 6
return 0;
}
🧠 总结:链表做题核心思路
🎯 必会5大技能
1️⃣ 会遍历(while走)
2️⃣ 会改指针(插入/删除)
3️⃣ 会画图(非常重要!)
4️⃣ 会双指针(快慢指针)
5️⃣ 会dummy节点(高级技巧)
🎁 终极口诀
链表问题不害怕,画图分析是关键
插入删除改指针,先连后断不出错
快慢指针找中点,环形问题也能解
反转链表三步走,prev cur next记心头