链表节点定义:
struct Node {
int data;
Node* next;
Node(int x) : data(x), next(nullptr) {}
};
Node* createNode(int data) {
return new Node(data);
}
头部插入:
Node* insertFront(Node* head, int data) {
Node* newNode = createNode(data);
newNode->next = head;
return newNode; // 返回新的头节点
}
尾部插入:
Node* insertBack(Node* head, int data) {
Node* newNode = createNode(data);
Node* current = head;
while (current->next) {
current = current->next;
}
current->next = newNode;
return head;
}
Node* findNode(Node* head, int data) {
Node* current = head;
while (current) {
if (current->data == data) {
return current;
}
current = current->next;
}
return nullptr; // 未找到
}
int getLength(Node* head) {
int count = 0;
Node* current = head;
while (current) {
count++;
current = current->next;
}
return count;
}
Node* insertAt(Node* head, int index, int data) {
if (index < 0) {
return head; // 无效索引
}
if (index == 0) {
return insertFront(head, data);
}
Node* newNode = createNode(data);
Node* current = head;
int currentIndex = 0;
// 找到插入位置的前一个节点
while (current && currentIndex < index - 1) {
current = current->next;
currentIndex++;
}
if (!current) {
delete newNode; // 索引越界,释放内存
return head;
}
newNode->next = current->next;
current->next = newNode;
return head;
}
Node* deleteFront(Node* head) {
if (!head) {
return nullptr;
}
Node* newHead = head->next;
delete head;
return newHead;
}
Node* deleteBack(Node* head) {
if (!head) {
return nullptr;
}
if (!head->next) {
delete head;
return nullptr;
}
Node* current = head;
while (current->next->next) {
current = current->next;
}
delete current->next;
current->next = nullptr;
return head;
}
Node* deleteAt(Node* head, int index) {
if (!head || index < 0) {
return head;
}
if (index == 0) {
return deleteFront(head);
}
Node* current = head;
int currentIndex = 0;
// 找到要删除节点的前一个节点
while (current->next && currentIndex < index - 1) {
current = current->next;
currentIndex++;
}
if (!current->next) {
return head; // 索引越界
}
Node* temp = current->next;
current->next = temp->next;
delete temp;
return head;
}
释放整个链表:
void deleteList(Node* head) {
Node* current = head;
while (current) {
Node* next = current->next;
delete current;
current = next;
}
}
bool search(Node* head, int data) {
return findNode(head, data) != nullptr;
}
int findIndex(Node* head, int data) {
Node* current = head;
int index = 0;
while (current) {
if (current->data == data) {
return index;
}
current = current->next;
index++;
}
return -1; // 未找到
}
Node* reverse(Node* head) {
Node* prev = nullptr;
Node* current = head;
Node* next = nullptr;
while (current) {
next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev; // 新的头节点
}
struct DoublyListNode {
int data;
DoublyListNode* prev; // 前驱指针
DoublyListNode* next; // 后继指针
};
struct DoublyNode {
int data;
DoublyNode* prev; // 前驱指针
DoublyNode* next; // 后继指针
DoublyNode(int x) : data(x), prev(nullptr), next(nullptr) {}
};
DoublyNode* createDoublyNode(int data) {
return new DoublyNode(data);
}
DoublyNode* insertFront(DoublyNode* head, int data) {
DoublyNode* newNode = createDoublyNode(data);
if (!head) {
return newNode;
}
newNode->next = head;
head->prev = newNode;
return newNode; // 返回新的头节点
}
DoublyNode* insertBack(DoublyNode* head, int data) {
DoublyNode* newNode = createDoublyNode(data);
if (!head) {
return newNode;
}
// 找到尾节点
DoublyNode* current = head;
while (current->next) {
current = current->next;
}
current->next = newNode;
newNode->prev = current;
return head;
}
DoublyNode* findDoublyNode(DoublyNode* head, int data) {
DoublyNode* current = head;
while (current) {
if (current->data == data) {
return current;
}
current = current->next;
}
return nullptr; // 未找到
}
int getDoublyLength(DoublyNode* head) {
int count = 0;
DoublyNode* current = head;
while (current) {
count++;
current = current->next;
}
return count;
}
DoublyNode* insertAt(DoublyNode* head, int index, int data) {
if (index < 0) {
return head; // 无效索引
}
if (index == 0) {
return insertFront(head, data);
}
DoublyNode* current = head;
int currentIndex = 0;
// 找到插入位置的节点
while (current && currentIndex < index) {
current = current->next;
currentIndex++;
}
if (!current) {
return head; // 索引越界
}
DoublyNode* newNode = createDoublyNode(data);
newNode->next = current;
newNode->prev = current->prev;
if (current->prev) {
current->prev->next = newNode;
}
current->prev = newNode;
return (index == 0) ? newNode : head;
}
DoublyNode* deleteFront(DoublyNode* head) {
if (!head) {
return nullptr;
}
DoublyNode* newHead = head->next;
if (newHead) {
newHead->prev = nullptr;
}
delete head;
return newHead;
}
DoublyNode* deleteBack(DoublyNode* head) {
if (!head) {
return nullptr;
}
if (!head->next) {
delete head;
return nullptr;
}
// 找到尾节点
DoublyNode* current = head;
while (current->next) {
current = current->next;
}
current->prev->next = nullptr;
delete current;
return head;
}
DoublyNode* deleteAt(DoublyNode* head, int index) {
if (!head || index < 0) {
return head;
}
if (index == 0) {
return deleteFront(head);
}
DoublyNode* current = head;
int currentIndex = 0;
// 找到要删除的节点
while (current && currentIndex < index) {
current = current->next;
currentIndex++;
}
if (!current) {
return head; // 索引越界
}
if (current->prev) {
current->prev->next = current->next;
}
if (current->next) {
current->next->prev = current->prev;
}
delete current;
return (index == 0) ? current->next : head;
}
void deleteDoublyList(DoublyNode* head) {
DoublyNode* current = head;
while (current) {
DoublyNode* next = current->next;
delete current;
current = next;
}
}
前向遍历显示:
void displayForward(DoublyNode* head) {
DoublyNode* current = head;
while (current) {
cout << current->data;
if (current->next) {
cout << " <-> ";
}
current = current->next;
}
cout << endl;
}
后向遍历显示:
void displayBackward(DoublyNode* head) {
if (!head) return;
// 先找到尾节点
DoublyNode* tail = head;
while (tail->next) {
tail = tail->next;
}
// 从尾节点向前遍历
DoublyNode* current = tail;
while (current) {
cout << current->data;
if (current->prev) {
cout << " <-> ";
}
current = current->prev;
}
cout << endl;
}
循环单链表节点定义:
struct CircularNode {
int data;
CircularNode* next;
CircularNode(int x) : data(x), next(nullptr) {}
};
创建新节点:
CircularNode* createCircularNode(int data) {
return new CircularNode(data);
}
CircularNode* insertCircular(CircularNode* tail, int data) {
CircularNode* newNode = createCircularNode(data);
if (!tail) {
// 第一个节点,指向自己
tail = newNode;
tail->next = tail;
} else {
// 在尾部插入
newNode->next = tail->next; // 新节点指向头节点
tail->next = newNode; // 尾节点指向新节点
tail = newNode; // 更新尾节点
}
return tail;
}
题目描述:合并两个有序链表
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode(0);
ListNode* current = dummy;
while (l1 && l2) {
if (l1->val <= l2->val) {
current->next = l1;
l1 = l1->next;
} else {
current->next = l2;
l2 = l2->next;
}
current = current->next;
}
current->next = l1 ? l1 : l2;
ListNode* result = dummy->next;
delete dummy;
return result;
}
解题思路:
创建虚拟头节点
双指针遍历
处理剩余节点
复杂度分析
关键技巧:
题目描述:判断链表是否有环并找出环的入口
bool hasCycle(ListNode* head) {
if (!head || !head->next) return false;
ListNode* slow = head;
ListNode* fast = head->next;
while (fast && fast->next) {
if (slow == fast) return true;
slow = slow->next;
fast = fast->next->next;
}
return false;
}
ListNode* detectCycle(ListNode* head) {
if (!head || !head->next) return nullptr;
ListNode* slow = head;
ListNode* fast = head;
// 快慢指针找相遇点
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) break;
}
if (!fast || !fast->next) return nullptr;
// 找环的入口
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
解题思路:
环检测原理
找环入口
边界条件
复杂度分析
数学证明:
题目描述:使用链表实现基数排序
struct Node {
int data;
Node* next;
Node(int x) : data(x), next(nullptr) {}
};
void radixSort(int arr[], int n) {
const int RADIX = 10;
Node* buckets[RADIX] = {nullptr};
int maxVal = arr[0];
for (int i = 1; i < n; i++) {
maxVal = max(maxVal, arr[i]);
}
for (int exp = 1; maxVal / exp > 0; exp *= 10) {
// 分配到桶中
for (int i = 0; i < n; i++) {
int digit = (arr[i] / exp) % RADIX;
Node* newNode = new Node(arr[i]);
if (!buckets[digit]) {
buckets[digit] = newNode;
} else {
Node* current = buckets[digit];
while (current->next) {
current = current->next;
}
current->next = newNode;
}
}
// 从桶中收集
int index = 0;
for (int i = 0; i < RADIX; i++) {
Node* current = buckets[i];
while (current) {
arr[index++] = current->data;
Node* temp = current;
current = current->next;
delete temp;
}
buckets[i] = nullptr;
}
}
}
解题思路:
基数排序原理
链表桶操作
算法步骤
复杂度分析
优化要点:
题目描述:使用链表实现并查集
struct ListNode {
int data;
ListNode* next;
ListNode* parent;
int rank;
ListNode(int x) : data(x), next(nullptr), parent(this), rank(0) {}
};
class DisjointSet {
private:
unordered_map<int, ListNode*> nodes;
public:
void makeSet(int x) {
if (nodes.find(x) == nodes.end()) {
nodes[x] = new ListNode(x);
}
}
ListNode* findSet(ListNode* node) {
if (node->parent != node) {
node->parent = findSet(node->parent);
}
return node->parent;
}
int findSet(int x) {
if (nodes.find(x) == nodes.end()) {
makeSet(x);
}
return findSet(nodes[x])->data;
}
void unionSets(int x, int y) {
makeSet(x);
makeSet(y);
ListNode* rootX = findSet(nodes[x]);
ListNode* rootY = findSet(nodes[y]);
if (rootX == rootY) return;
if (rootX->rank < rootY->rank) {
rootX->parent = rootY;
} else if (rootX->rank > rootY->rank) {
rootY->parent = rootX;
} else {
rootY->parent = rootX;
rootX->rank++;
}
}
bool sameSet(int x, int y) {
return findSet(x) == findSet(y);
}
};
解题思路:
并查集数据结构
路径压缩优化
按秩合并优化
复杂度分析
应用场景:
题目描述:使用链表实现队列操作
struct Node {
int data;
Node* next;
Node(int x) : data(x), next(nullptr) {}
};
class LinkedListQueue {
private:
Node* front;
Node* rear;
int size;
public:
LinkedListQueue() : front(nullptr), rear(nullptr), size(0) {}
~LinkedListQueue() {
while (!isEmpty()) {
dequeue();
}
}
void enqueue(int x) {
Node* newNode = new Node(x);
if (isEmpty()) {
front = rear = newNode;
} else {
rear->next = newNode;
rear = newNode;
}
size++;
}
int dequeue() {
if (isEmpty()) {
throw runtime_error("Queue is empty");
}
Node* temp = front;
int value = temp->data;
front = front->next;
if (!front) {
rear = nullptr;
}
delete temp;
size--;
return value;
}
int peek() const {
if (isEmpty()) {
throw runtime_error("Queue is empty");
}
return front->data;
}
bool isEmpty() const {
return front == nullptr;
}
int getSize() const {
return size;
}
};
解题思路:
队列FIFO特性
双指针设计
边界条件处理
操作复杂度
设计要点:
题目描述:使用链表实现栈操作
struct StackNode {
int data;
StackNode* next;
StackNode(int x) : data(x), next(nullptr) {}
};
class LinkedListStack {
private:
StackNode* top;
int size;
public:
LinkedListStack() : top(nullptr), size(0) {}
~LinkedListStack() {
while (!isEmpty()) {
pop();
}
}
void push(int x) {
StackNode* newNode = new StackNode(x);
newNode->next = top;
top = newNode;
size++;
}
int pop() {
if (isEmpty()) {
throw runtime_error("Stack is empty");
}
StackNode* temp = top;
int value = temp->data;
top = top->next;
delete temp;
size--;
return value;
}
int peek() const {
if (isEmpty()) {
throw runtime_error("Stack is empty");
}
return top->data;
}
bool isEmpty() const {
return top == nullptr;
}
int getSize() const {
return size;
}
};
解题思路:
栈LIFO特性
头节点作为栈顶
操作实现
复杂度分析
优势特点:
题目描述:反转链表的多种方法
class Solution {
public:
// 方法1:迭代反转
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* current = head;
while (current) {
ListNode* next = current->next;
current->next = prev;
prev = current;
current = next;
}
return prev;
}
// 方法2:递归反转
ListNode* reverseListRecursive(ListNode* head) {
if (!head || !head->next) {
return head;
}
ListNode* newHead = reverseListRecursive(head->next);
head->next->next = head;
head->next = nullptr;
return newHead;
}
// 方法3:头插法反转
ListNode* reverseListInsert(ListNode* head) {
ListNode dummy(0);
dummy.next = nullptr;
while (head) {
ListNode* next = head->next;
head->next = dummy.next;
dummy.next = head;
head = next;
}
return dummy.next;
}
};
解题思路:
迭代法(三指针)
递归法
头插法
方法比较
选择建议:
题目描述:链表排序(归并排序)
class Solution {
public:
ListNode* sortList(ListNode* head) {
if (!head || !head->next) {
return head;
}
// 找到中间节点
ListNode* mid = findMiddle(head);
ListNode* right = mid->next;
mid->next = nullptr;
// 递归排序
ListNode* left = sortList(head);
right = sortList(right);
// 合并有序链表
return merge(left, right);
}
private:
ListNode* findMiddle(ListNode* head) {
ListNode* slow = head;
ListNode* fast = head->next;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
}
return slow;
}
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode dummy(0);
ListNode* current = &dummy;
while (l1 && l2) {
if (l1->val <= l2->val) {
current->next = l1;
l1 = l1->next;
} else {
current->next = l2;
l2 = l2->next;
}
current = current->next;
}
current->next = l1 ? l1 : l2;
return dummy.next;
}
};
解题思路:
归并排序选择
找中点技巧
递归排序
合并有序链表
复杂度分析
优化要点:
指针基础:
数组与指针:
字符指针:
结构体指针:
单向链表:
双向链表:
链表算法:
复杂链表操作:
高级数据结构:

这个讲义使用了Awesome Marp主题的蓝色风格。 内容针对竞赛选手设计,注重基础概念和实际应用。
封底页: - 感谢学生的参与 - 提供联系方式或其他资源 - 鼓励学生继续学习和实践