C++ STL完全指南:从入门到精通数据结构与算法

C++ STL完全指南:从入门到精通数据结构与算法

【免费下载链接】DataStructures-Algorithms This repo contains links of resources, theory subjects content and DSA questions & their solution for interview preparation from different websites like geeksforgeeks, leetcode, etc. 【免费下载链接】DataStructures-Algorithms 项目地址: https://gitcode.com/gh_mirrors/dat/DataStructures-Algorithms

为什么STL是C++开发者的必备技能?

你是否还在手动实现动态数组、链表和哈希表?是否在排序算法上浪费数小时却仍有性能隐患?C++标准模板库(Standard Template Library, STL)通过提供工业级数据结构优化算法,让开发者专注于业务逻辑而非重复造轮子。本文将系统讲解STL的核心组件,结合LeetCode实战案例,帮你掌握从基础容器到高级算法的全方位应用。

读完本文你将获得

  • 容器选择决策指南(时间/空间复杂度对比)
  • 15+常用算法实战技巧(排序/查找/哈希)
  • 性能优化技巧(避免迭代器失效/内存泄漏)
  • 10个LeetCode高频题解的STL最佳实践

STL体系架构:6大组件全景图

mermaid

容器家族:选择指南与性能对比

容器类型底层实现随机访问插入/删除效率典型应用场景
vector动态数组O(1)尾部O(1),中间O(n)存储连续数据、频繁访问
list双向链表O(n)任意位置O(1)频繁插入删除
deque分段数组O(1)头尾O(1)双端操作队列
map红黑树O(log n)O(log n)键值对有序存储
unordered_map哈希表平均O(1)平均O(1)快速查找(无顺序要求)
priority_queueO(n)插入O(log n)Top K问题

⚠️ 警告:vector的realloc机制可能导致迭代器失效,插入大量元素前建议使用reserve()预分配空间

序列式容器实战:从vector到deque

vector:动态数组的艺术

vector是STL中使用最广泛的容器,其动态扩容机制完美平衡了空间效率与访问速度。以下是LeetCode 3Sum问题的最优实现,展示vector的排序、去重和双指针技巧:

vector<vector<int>> threeSum(vector<int>& nums) {
    vector<vector<int>> ans;
    sort(nums.begin(), nums.end());  // 利用algorithm库排序
    
    for (int i = 0; i < nums.size(); ++i) {
        if (i > 0 && nums[i] == nums[i-1]) continue;  // 去重
        
        int left = i + 1, right = nums.size() - 1;
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];
            if (sum == 0) {
                ans.push_back({nums[i], nums[left], nums[right]});
                // 跳过重复元素
                while (left < right && nums[left] == nums[left+1]) left++;
                while (left < right && nums[right] == nums[right-1]) right--;
                left++; right--;
            } else if (sum < 0) {
                left++;
            } else {
                right--;
            }
        }
    }
    return ans;
}

关键操作复杂度

  • 随机访问:O(1)
  • 尾部插入:O(1)( amortized )
  • 中间插入:O(n)
  • 排序:O(n log n)

list:双向链表的极致灵活

list通过节点指针实现高效插入删除,但牺牲了随机访问能力。在LRU缓存实现中,list的splice操作可实现O(1)时间的节点移动:

// LRU Cache中的list应用(简化版)
class LRUCache {
    list<int> cache;  // 维护访问顺序
    unordered_map<int, pair<int, list<int>::iterator>> mp;  // 哈希表+迭代器
    int capacity;
    
public:
    LRUCache(int cap) : capacity(cap) {}
    
    int get(int key) {
        if (!mp.count(key)) return -1;
        
        // 将访问节点移到头部(O(1)操作)
        cache.splice(cache.begin(), cache, mp[key].second);
        return mp[key].first;
    }
    
    void put(int key, int value) {
        if (mp.count(key)) {
            cache.erase(mp[key].second);  // 已有节点先删除
        } else if (cache.size() == capacity) {
            // 缓存满时删除尾部节点
            mp.erase(cache.back());
            cache.pop_back();
        }
        
        // 插入新节点到头部
        cache.push_front(key);
        mp[key] = {value, cache.begin()};
    }
};

关联式容器深度解析

红黑树VS哈希表:性能对决

mermaid

unordered_map实战:两数之和问题

LeetCode第一题的最优解利用哈希表实现O(n)时间复杂度:

vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> prev;  // 存储值到索引的映射
    
    for (int i = 0; i < nums.size(); ++i) {
        int complement = target - nums[i];
        if (prev.count(complement)) {
            return {prev[complement], i};  // 找到配对
        }
        prev[nums[i]] = i;  // 延迟插入避免重复使用
    }
    
    return {};  // 题目保证有解
}

💡 技巧:使用reserve(n)预分配哈希表空间可避免多次rehash,在大数据量时性能提升30%+

set去重与排序特性:3Sum问题优化

vector<vector<int>> threeSum(vector<int>& nums) {
    set<vector<int>> result;  // 自动排序+去重
    sort(nums.begin(), nums.end());
    
    for (int i = 0; i < nums.size(); ++i) {
        if (nums[i] > 0) break;  // 剪枝:最小数为正则无解
        
        int left = i + 1, right = nums.size() - 1;
        while (left < right) {
            int sum = nums[i] + nums[left] + nums[right];
            if (sum == 0) {
                result.insert({nums[i], nums[left], nums[right]});
                left++; right--;
            } else if (sum < 0) {
                left++;
            } else {
                right--;
            }
        }
    }
    
    return vector<vector<int>>(result.begin(), result.end());
}

算法库:STL的多功能工具集

排序算法全解析

STL的sort函数采用** introsort**算法(快速排序+堆排序+插入排序的混合),在大多数情况下性能接近O(n log n)。以下是常见排序场景的最佳实践:

// 1. 基本排序
vector<int> nums = {3,1,4,1,5,9};
sort(nums.begin(), nums.end());  // 默认升序 → [1,1,3,4,5,9]

// 2. 降序排序
sort(nums.begin(), nums.end(), greater<int>());  // [9,5,4,3,1,1]

// 3. 自定义比较器(按绝对值排序)
sort(nums.begin(), nums.end(), [](int a, int b) {
    return abs(a) < abs(b);  // [-3,1,4,1,5,9] → [1,1,3,4,5,9]
});

// 4. 部分排序(获取前k小元素)
vector<int> topK(nums.size());
partial_sort_copy(nums.begin(), nums.end(), 
                 topK.begin(), topK.begin() + 3);  // 获取前3小元素

// 5. 稳定排序(相等元素保持原有顺序)
stable_sort(nums.begin(), nums.end());

查找算法实战

// 1. 二分查找(必须先排序)
vector<int> sorted_nums = {1,3,5,7,9};
bool found = binary_search(sorted_nums.begin(), sorted_nums.end(), 5);  // true

// 2. 查找第一个大于等于x的元素
auto it = lower_bound(sorted_nums.begin(), sorted_nums.end(), 4);  // 指向5(索引2)

// 3. 查找最后一个小于等于x的元素
it = upper_bound(sorted_nums.begin(), sorted_nums.end(), 6);  // 指向5(索引2)

// 4. 统计元素出现次数(需排序)
int count = upper_bound(sorted_nums.begin(), sorted_nums.end(), 5) - 
           lower_bound(sorted_nums.begin(), sorted_nums.end(), 5);  // 1次

排列组合生成

vector<int> nums = {1,2,3};

// 生成下一个排列
next_permutation(nums.begin(), nums.end());  // {1,3,2}
next_permutation(nums.begin(), nums.end());  // {2,1,3}

// 生成所有排列
sort(nums.begin(), nums.end());  // 先排序
do {
    // 处理当前排列 {1,2,3}, {1,3,2}, ..., {3,2,1}
} while (next_permutation(nums.begin(), nums.end()));

容器适配器:栈与队列的高级应用

单调栈:解决Next Greater Element问题

vector<int> nextGreaterElements(vector<int>& nums) {
    int n = nums.size();
    vector<int> res(n, -1);
    stack<int> st;  // 存储索引,保持栈内元素递减
    
    for (int i = 2*n - 1; i >= 0; --i) {

【免费下载链接】DataStructures-Algorithms This repo contains links of resources, theory subjects content and DSA questions & their solution for interview preparation from different websites like geeksforgeeks, leetcode, etc. 【免费下载链接】DataStructures-Algorithms 项目地址: https://gitcode.com/gh_mirrors/dat/DataStructures-Algorithms

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值