Skip to content

STL标准库

概述

STL(Standard Template Library)是C++标准库的重要组成部分,提供了容器、迭代器、算法和函数对象等通用组件。

容器

vector动态数组

cpp
#include <iostream>
#include <vector>

using namespace std;

int main() {
    vector<int> v1;
    
    v1.push_back(10);
    v1.push_back(20);
    v1.push_back(30);
    
    vector<int> v2 = {1, 2, 3, 4, 5};
    
    cout << "v2大小: " << v2.size() << endl;
    cout << "v2容量: " << v2.capacity() << endl;
    
    cout << "元素访问:" << endl;
    cout << "v2[0] = " << v2[0] << endl;
    cout << "v2.at(1) = " << v2.at(1) << endl;
    cout << "v2.front() = " << v2.front() << endl;
    cout << "v2.back() = " << v2.back() << endl;
    
    v2.insert(v2.begin() + 2, 100);
    cout << "插入后: ";
    for (int x : v2) cout << x << " ";
    cout << endl;
    
    v2.erase(v2.begin() + 2);
    cout << "删除后: ";
    for (int x : v2) cout << x << " ";
    cout << endl;
    
    v2.pop_back();
    cout << "弹出后: ";
    for (int x : v2) cout << x << " ";
    cout << endl;
    
    v2.clear();
    cout << "清空后大小: " << v2.size() << endl;
    
    return 0;
}

list链表

cpp
#include <iostream>
#include <list>

using namespace std;

int main() {
    list<int> lst = {1, 2, 3, 4, 5};
    
    lst.push_front(0);
    lst.push_back(6);
    
    cout << "链表内容: ";
    for (int x : lst) cout << x << " ";
    cout << endl;
    
    lst.insert(++lst.begin(), 100);
    cout << "插入后: ";
    for (int x : lst) cout << x << " ";
    cout << endl;
    
    lst.remove(100);
    cout << "删除100后: ";
    for (int x : lst) cout << x << " ";
    cout << endl;
    
    lst.reverse();
    cout << "反转后: ";
    for (int x : lst) cout << x << " ";
    cout << endl;
    
    lst.sort();
    cout << "排序后: ";
    for (int x : lst) cout << x << " ";
    cout << endl;
    
    lst.unique();
    cout << "去重后: ";
    for (int x : lst) cout << x << " ";
    cout << endl;
    
    return 0;
}

deque双端队列

cpp
#include <iostream>
#include <deque>

using namespace std;

int main() {
    deque<int> dq = {2, 3, 4};
    
    dq.push_front(1);
    dq.push_back(5);
    
    cout << "双端队列: ";
    for (int x : dq) cout << x << " ";
    cout << endl;
    
    cout << "front: " << dq.front() << endl;
    cout << "back: " << dq.back() << endl;
    
    dq.pop_front();
    dq.pop_back();
    
    cout << "弹出两端后: ";
    for (int x : dq) cout << x << " ";
    cout << endl;
    
    return 0;
}

stack栈

cpp
#include <iostream>
#include <stack>

using namespace std;

int main() {
    stack<int> s;
    
    s.push(10);
    s.push(20);
    s.push(30);
    
    cout << "栈顶: " << s.top() << endl;
    cout << "大小: " << s.size() << endl;
    
    while (!s.empty()) {
        cout << "弹出: " << s.top() << endl;
        s.pop();
    }
    
    return 0;
}

queue队列

cpp
#include <iostream>
#include <queue>

using namespace std;

int main() {
    queue<int> q;
    
    q.push(10);
    q.push(20);
    q.push(30);
    
    cout << "队首: " << q.front() << endl;
    cout << "队尾: " << q.back() << endl;
    cout << "大小: " << q.size() << endl;
    
    while (!q.empty()) {
        cout << "出队: " << q.front() << endl;
        q.pop();
    }
    
    return 0;
}

priority_queue优先队列

cpp
#include <iostream>
#include <queue>
#include <vector>
#include <functional>

using namespace std;

int main() {
    priority_queue<int> pq;
    
    pq.push(30);
    pq.push(10);
    pq.push(50);
    pq.push(20);
    
    cout << "大顶堆出队顺序:" << endl;
    while (!pq.empty()) {
        cout << pq.top() << " ";
        pq.pop();
    }
    cout << endl;
    
    priority_queue<int, vector<int>, greater<int>> minPQ;
    minPQ.push(30);
    minPQ.push(10);
    minPQ.push(50);
    minPQ.push(20);
    
    cout << "小顶堆出队顺序:" << endl;
    while (!minPQ.empty()) {
        cout << minPQ.top() << " ";
        minPQ.pop();
    }
    cout << endl;
    
    return 0;
}

set集合

cpp
#include <iostream>
#include <set>

using namespace std;

int main() {
    set<int> s = {5, 3, 1, 4, 2};
    
    s.insert(6);
    s.insert(3);
    
    cout << "集合内容(自动排序): ";
    for (int x : s) cout << x << " ";
    cout << endl;
    
    auto it = s.find(3);
    if (it != s.end()) {
        cout << "找到元素: " << *it << endl;
    }
    
    s.erase(3);
    cout << "删除3后: ";
    for (int x : s) cout << x << " ";
    cout << endl;
    
    cout << "count(5): " << s.count(5) << endl;
    
    auto range = s.equal_range(4);
    cout << "equal_range(4): [" << *range.first << ", " << *range.second << "]" << endl;
    
    return 0;
}

map映射

cpp
#include <iostream>
#include <map>
#include <string>

using namespace std;

int main() {
    map<string, int> scores;
    
    scores["张三"] = 85;
    scores["李四"] = 90;
    scores["王五"] = 78;
    
    scores.insert({"赵六", 88});
    
    scores.emplace("钱七", 95);
    
    cout << "成绩表:" << endl;
    for (const auto &p : scores) {
        cout << p.first << ": " << p.second << endl;
    }
    
    cout << "\n张三的成绩: " << scores["张三"] << endl;
    cout << "李四的成绩: " << scores.at("李四") << endl;
    
    auto it = scores.find("王五");
    if (it != scores.end()) {
        cout << "找到王五: " << it->second << endl;
    }
    
    scores.erase("王五");
    cout << "\n删除王五后的人数: " << scores.size() << endl;
    
    if (scores.count("张三")) {
        cout << "张三在成绩表中" << endl;
    }
    
    return 0;
}

unordered_map哈希映射

cpp
#include <iostream>
#include <unordered_map>
#include <string>

using namespace std;

int main() {
    unordered_map<string, int> um;
    
    um["apple"] = 1;
    um["banana"] = 2;
    um["cherry"] = 3;
    
    cout << "哈希映射内容:" << endl;
    for (const auto &p : um) {
        cout << p.first << ": " << p.second << endl;
    }
    
    cout << "\n查找 banana: " << um["banana"] << endl;
    
    cout << "桶数量: " << um.bucket_count() << endl;
    cout << "负载因子: " << um.load_factor() << endl;
    
    return 0;
}

迭代器

迭代器类型

cpp
#include <iostream>
#include <vector>
#include <list>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};
    
    cout << "正向迭代器: ";
    for (auto it = v.begin(); it != v.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
    
    cout << "反向迭代器: ";
    for (auto it = v.rbegin(); it != v.rend(); ++it) {
        cout << *it << " ";
    }
    cout << endl;
    
    auto it = v.begin();
    advance(it, 2);
    cout << "advance后: " << *it << endl;
    
    cout << "distance: " << distance(v.begin(), it) << endl;
    
    auto nextIt = next(it);
    cout << "next: " << *nextIt << endl;
    
    auto prevIt = prev(it);
    cout << "prev: " << *prevIt << endl;
    
    return 0;
}

算法

排序算法

cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> v = {5, 2, 8, 1, 9, 3, 7, 4, 6};
    
    vector<int> v1 = v;
    sort(v1.begin(), v1.end());
    cout << "升序排序: ";
    for (int x : v1) cout << x << " ";
    cout << endl;
    
    vector<int> v2 = v;
    sort(v2.begin(), v2.end(), greater<int>());
    cout << "降序排序: ";
    for (int x : v2) cout << x << " ";
    cout << endl;
    
    vector<int> v3 = v;
    partial_sort(v3.begin(), v3.begin() + 3, v3.end());
    cout << "部分排序(前3个最小): ";
    for (int x : v3) cout << x << " ";
    cout << endl;
    
    vector<int> v4 = v;
    nth_element(v4.begin(), v4.begin() + 4, v4.end());
    cout << "第5小元素: " << v4[4] << endl;
    
    return 0;
}

查找算法

cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    auto it = find(v.begin(), v.end(), 5);
    if (it != v.end()) {
        cout << "找到5,位置: " << distance(v.begin(), it) << endl;
    }
    
    auto it2 = find_if(v.begin(), v.end(), [](int x) { return x > 5; });
    if (it2 != v.end()) {
        cout << "第一个大于5的数: " << *it2 << endl;
    }
    
    bool found = binary_search(v.begin(), v.end(), 6);
    cout << "二分查找6: " << (found ? "找到" : "未找到") << endl;
    
    auto range = equal_range(v.begin(), v.end(), 5);
    cout << "equal_range(5): [" << *range.first << ", " << *range.second << "]" << endl;
    
    int cnt = count(v.begin(), v.end(), 5);
    cout << "5出现次数: " << cnt << endl;
    
    int cnt2 = count_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; });
    cout << "偶数个数: " << cnt2 << endl;
    
    return 0;
}

修改算法

cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3, 4, 5};
    
    vector<int> v2(v.size());
    copy(v.begin(), v.end(), v2.begin());
    
    cout << "复制后v2: ";
    for (int x : v2) cout << x << " ";
    cout << endl;
    
    fill(v2.begin(), v2.end(), 0);
    cout << "填充后v2: ";
    for (int x : v2) cout << x << " ";
    cout << endl;
    
    transform(v.begin(), v.end(), v.begin(), [](int x) { return x * 2; });
    cout << "transform后v: ";
    for (int x : v) cout << x << " ";
    cout << endl;
    
    replace(v.begin(), v.end(), 4, 100);
    cout << "替换后v: ";
    for (int x : v) cout << x << " ";
    cout << endl;
    
    vector<int> v3 = {1, 2, 2, 3, 3, 3, 4};
    auto last = unique(v3.begin(), v3.end());
    v3.erase(last, v3.end());
    cout << "去重后v3: ";
    for (int x : v3) cout << x << " ";
    cout << endl;
    
    reverse(v.begin(), v.end());
    cout << "反转后v: ";
    for (int x : v) cout << x << " ";
    cout << endl;
    
    return 0;
}

排列算法

cpp
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main() {
    vector<int> v = {1, 2, 3};
    
    cout << "全排列:" << endl;
    int count = 0;
    do {
        cout << ++count << ": ";
        for (int x : v) cout << x << " ";
        cout << endl;
    } while (next_permutation(v.begin(), v.end()));
    
    vector<int> v2 = {3, 2, 1};
    prev_permutation(v2.begin(), v2.end());
    cout << "prev_permutation后: ";
    for (int x : v2) cout << x << " ";
    cout << endl;
    
    return 0;
}

函数对象

lambda表达式

cpp
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

using namespace std;

int main() {
    auto add = [](int a, int b) { return a + b; };
    cout << "add(3, 4) = " << add(3, 4) << endl;
    
    int x = 10;
    auto addX = [x](int a) { return a + x; };
    cout << "addX(5) = " << addX(5) << endl;
    
    auto addRef = [&x](int a) { 
        x = a + x; 
        return x; 
    };
    cout << "addRef(5) = " << addRef(5) << ", x = " << x << endl;
    
    vector<int> v = {5, 2, 8, 1, 9};
    sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
    cout << "降序排序: ";
    for (int n : v) cout << n << " ";
    cout << endl;
    
    int sum = 0;
    for_each(v.begin(), v.end(), [&sum](int n) { sum += n; });
    cout << "总和: " << sum << endl;
    
    return 0;
}

function和bind

cpp
#include <iostream>
#include <functional>
#include <string>

using namespace std;

int add(int a, int b) {
    return a + b;
}

class Calculator {
public:
    int multiply(int a, int b) {
        return a * b;
    }
};

int main() {
    function<int(int, int)> func1 = add;
    cout << "func1(3, 4) = " << func1(3, 4) << endl;
    
    function<int(int, int)> func2 = [](int a, int b) { return a - b; };
    cout << "func2(10, 3) = " << func2(10, 3) << endl;
    
    Calculator calc;
    function<int(int, int)> func3 = bind(&Calculator::multiply, &calc, placeholders::_1, placeholders::_2);
    cout << "func3(3, 4) = " << func3(3, 4) << endl;
    
    auto addFive = bind(add, placeholders::_1, 5);
    cout << "addFive(10) = " << addFive(10) << endl;
    
    return 0;
}

智能指针

unique_ptr

cpp
#include <iostream>
#include <memory>
#include <string>

using namespace std;

class Resource {
public:
    string name;
    Resource(string n) : name(n) {
        cout << "创建: " << name << endl;
    }
    ~Resource() {
        cout << "销毁: " << name << endl;
    }
};

int main() {
    {
        unique_ptr<Resource> ptr1 = make_unique<Resource>("资源1");
        cout << "ptr1: " << ptr1->name << endl;
        
        unique_ptr<Resource> ptr2 = move(ptr1);
        cout << "移动后 ptr2: " << ptr2->name << endl;
        cout << "ptr1 是否为空: " << (ptr1 ? "否" : "是") << endl;
    }
    
    cout << "--- 离开作用域 ---" << endl;
    
    return 0;
}

shared_ptr

cpp
#include <iostream>
#include <memory>
#include <string>

using namespace std;

class SharedResource {
public:
    string name;
    SharedResource(string n) : name(n) {
        cout << "创建: " << name << endl;
    }
    ~SharedResource() {
        cout << "销毁: " << name << endl;
    }
};

int main() {
    shared_ptr<SharedResource> ptr1 = make_shared<SharedResource>("共享资源");
    cout << "引用计数: " << ptr1.use_count() << endl;
    
    {
        shared_ptr<SharedResource> ptr2 = ptr1;
        cout << "ptr2创建后引用计数: " << ptr1.use_count() << endl;
        
        shared_ptr<SharedResource> ptr3 = ptr1;
        cout << "ptr3创建后引用计数: " << ptr1.use_count() << endl;
    }
    
    cout << "离开作用域后引用计数: " << ptr1.use_count() << endl;
    
    return 0;
}

weak_ptr

cpp
#include <iostream>
#include <memory>

using namespace std;

class Node {
public:
    string name;
    weak_ptr<Node> next;
    
    Node(string n) : name(n) {
        cout << "创建节点: " << name << endl;
    }
    ~Node() {
        cout << "销毁节点: " << name << endl;
    }
};

int main() {
    auto node1 = make_shared<Node>("节点1");
    auto node2 = make_shared<Node>("节点2");
    
    node1->next = node2;
    node2->next = node1;
    
    cout << "node1引用计数: " << node1.use_count() << endl;
    cout << "node2引用计数: " << node2.use_count() << endl;
    
    if (auto locked = node1->next.lock()) {
        cout << "node1的下一个节点: " << locked->name << endl;
    }
    
    return 0;
}

实践示例

学生成绩管理系统

cpp
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <memory>
#include <iomanip>

using namespace std;

class Student {
public:
    int id;
    string name;
    map<string, double> scores;
    
    Student(int i, string n) : id(i), name(n) {}
    
    void addScore(const string &subject, double score) {
        scores[subject] = score;
    }
    
    double getAverage() const {
        if (scores.empty()) return 0;
        double sum = 0;
        for (const auto &p : scores) {
            sum += p.second;
        }
        return sum / scores.size();
    }
    
    double getTotal() const {
        double sum = 0;
        for (const auto &p : scores) {
            sum += p.second;
        }
        return sum;
    }
    
    void display() const {
        cout << "学号: " << id << ", 姓名: " << name << endl;
        cout << "成绩: ";
        for (const auto &p : scores) {
            cout << p.first << "=" << p.second << " ";
        }
        cout << "\n总分: " << getTotal() << ", 平均分: " << fixed << setprecision(2) << getAverage() << endl;
    }
};

class GradeManager {
private:
    vector<shared_ptr<Student>> students;
    
public:
    void addStudent(int id, const string &name) {
        students.push_back(make_shared<Student>(id, name));
        cout << "添加学生成功: " << name << endl;
    }
    
    void addScore(int id, const string &subject, double score) {
        auto it = find_if(students.begin(), students.end(), 
            [id](const shared_ptr<Student> &s) { return s->id == id; });
        
        if (it != students.end()) {
            (*it)->addScore(subject, score);
            cout << "添加成绩成功" << endl;
        } else {
            cout << "未找到学生" << endl;
        }
    }
    
    void displayAll() const {
        cout << "\n" << string(70, '=') << endl;
        cout << left << setw(8) << "学号" 
             << setw(12) << "姓名"
             << setw(10) << "总分"
             << setw(10) << "平均分" << endl;
        cout << string(70, '-') << endl;
        
        for (const auto &s : students) {
            cout << left << setw(8) << s->id 
                 << setw(12) << s->name
                 << setw(10) << fixed << setprecision(1) << s->getTotal()
                 << setw(10) << fixed << setprecision(2) << s->getAverage() << endl;
        }
        cout << string(70, '=') << endl;
    }
    
    void sortByTotal() {
        sort(students.begin(), students.end(), 
            [](const shared_ptr<Student> &a, const shared_ptr<Student> &b) {
                return a->getTotal() > b->getTotal();
            });
        cout << "按总分排序完成" << endl;
    }
    
    void findStudent(int id) const {
        auto it = find_if(students.begin(), students.end(), 
            [id](const shared_ptr<Student> &s) { return s->id == id; });
        
        if (it != students.end()) {
            cout << "\n找到学生:" << endl;
            (*it)->display();
        } else {
            cout << "未找到学号为 " << id << " 的学生" << endl;
        }
    }
    
    void getTopStudents(int n) const {
        vector<shared_ptr<Student>> sorted = students;
        sort(sorted.begin(), sorted.end(), 
            [](const shared_ptr<Student> &a, const shared_ptr<Student> &b) {
                return a->getTotal() > b->getTotal();
            });
        
        cout << "\n前" << n << "名学生:" << endl;
        int count = min(n, (int)sorted.size());
        for (int i = 0; i < count; i++) {
            cout << "第" << (i + 1) << "名: " << sorted[i]->name 
                 << " (总分: " << sorted[i]->getTotal() << ")" << endl;
        }
    }
};

int main() {
    GradeManager manager;
    
    manager.addStudent(1001, "张三");
    manager.addStudent(1002, "李四");
    manager.addStudent(1003, "王五");
    manager.addStudent(1004, "赵六");
    
    manager.addScore(1001, "数学", 85);
    manager.addScore(1001, "英语", 90);
    manager.addScore(1001, "物理", 78);
    
    manager.addScore(1002, "数学", 92);
    manager.addScore(1002, "英语", 88);
    manager.addScore(1002, "物理", 95);
    
    manager.addScore(1003, "数学", 76);
    manager.addScore(1003, "英语", 82);
    manager.addScore(1003, "物理", 80);
    
    manager.addScore(1004, "数学", 88);
    manager.addScore(1004, "英语", 85);
    manager.addScore(1004, "物理", 90);
    
    manager.displayAll();
    
    manager.sortByTotal();
    manager.displayAll();
    
    manager.findStudent(1002);
    
    manager.getTopStudents(3);
    
    return 0;
}

小结

STL核心组件:

组件说明
容器vector, list, map, set等
迭代器遍历容器的统一接口
算法sort, find, transform等
函数对象lambda, function, bind

智能指针:

类型说明
unique_ptr独占所有权
shared_ptr共享所有权
weak_ptr弱引用,避免循环引用

导航