c++数据结构4——链表结构详解
一、链表的物理结构与核心概念
1.1 物理存储的非连续性
链表通过动态内存分配实现物理存储的非连续性。每个节点包含两部分:
- 数据域:存储实际数据(如
int value
) - 指针域:存储下一个节点的地址(如
node* next
)
物理结构示意图:
每个节点在内存中独立分布,通过指针串联形成逻辑顺序。
1.2 头结点的重要性
头结点是链表的入口,通过head
指针访问整个链表。若链表为空,head=NULL
。例如:
node* head = nullptr; // 空链表
二、单链表的实现与操作
2.1 节点动态管理
struct Node {
int value;
Node* next;
};
Node* newNode = new Node{5, nullptr}; // 创建新节点
delete new; // 释放节点
new和delete二者必须配对使用
2.2 核心操作实现
2.2.1 尾插法(效率分析)
void append(int x) {Node* newNode = new Node{x, nullptr};if (head == nullptr) {head = newNode; // 空链表特殊处理} else {Node* p = head;while (p->next) p = p->next; // 遍历到尾部p->next = newNode;} }
时间复杂度:O(n)(需遍历到尾部)
2.2.2 指定位置插入
void insert(int x, int pos) {Node* newNode = new Node{x, nullptr};if (pos == 0) { // 头插newNode->next = head;head = newNode;} else {Node* p = head;for (int i=0; i<pos-1 && p; i++) p = p->next;newNode->next = p->next;p->next = newNode;} }
边界条件:需处理插入位置超出链表长度的情况
三、STL List的底层实现与特性
3.1 双向循环链表结构
STL的list
采用双向循环链表实现,每个节点结构:
template<typename T> struct ListNode {T data;ListNode* prev;ListNode* next;ListNode(const T& val) : data(val), prev(nullptr), next(nullptr) {} };
物理结构示意图:
3.2 核心操作优势
3.2.1 高效插入/删除
list<int> a; a.push_back(10); // O(1) a.insert(a.begin(), 5); // O(1)
时间复杂度:任意位置插入/删除均为O(1)
3.2.2 双向迭代器
list<int>::iterator it = a.begin(); it++; // 前向移动 list<int>::reverse_iterator rit = a.rbegin(); rit--; // 后向移动
四、链表与STL List对比
特性 | 手动链表 | STL List |
---|---|---|
内存管理 | 需手动new/delete | 自动内存管理 |
双向操作 | 仅单向(需自定义) | 原生支持双向 |
插入/删除效率 | O(n)(尾插需遍历) | O(1)(已知迭代器位置) |
适用场景 | 学习数据结构基础 | 高频插入/删除的中间数据处理 |
五、教学示例:链表与STL List实战
5.1 单链表实现(完整代码)
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
Node(int x) : data(x), next(nullptr) {}
};
void printList(Node* head) {
Node* p = head;
while (p) {
cout << p->data << " -> ";
p = p->next;
}
cout << "nullptr" << endl;
}
int main() {
Node* head = new Node(1);
head->next = new Node(2);
head->next->next = new Node(3);
printList(head); // 1 -> 2 -> 3 -> nullptr
// 释放内存
while (head) {
Node* tmp = head;
head = head->next;
delete tmp;
}
return 0;
}
5.2 STL List应用
#include <list> #include <algorithm>void listDemo() {list<int> a;// 高效插入a.push_front(10);a.push_back(20);a.insert(a.begin(), 5); // 在头部插入// 反向遍历for (auto rit = a.rbegin(); rit != a.rend(); ++rit) {cout << *rit << " "; // 输出:20 10 5}// 删除元素a.remove(10); // 删除所有值为10的元素 }