STL 入门 + 三道高频面试题

STL 入门 + 三道高频面试题(二叉树层序 / 重建二叉树 / 两栈实现队列)

不懂 STL,不要说你会 C++。

本文整理了 STL 的核心概念、重要版本、六大组件,并结合三道经典面试题(JZ78、JZ7、JZ9)给出完整代码与解析,最后附带一份常见 C++ 面试问答。


一、STL 简介

1. 什么是 STL

STL(Standard Template Library,标准模板库) 是 C++ 标准库的核心组成部分。

它不仅仅是一个可复用的组件库,更是一个包罗数据结构与算法的软件框架。

2. STL 的发展版本(了解即可,但面试可能被问)

版本 特点
HP 版本 始祖,开源
P.J. 版本 VC++ 使用,不可修改,可读性差
RW 版本 C++Builder 使用
SGI 版本 Linux GCC 使用,可读性好,推荐学习参考

我们平时读 STL 源码,主要参考 SGI 版本。

3. STL 六大组件

  1. 容器(vector、list、map...)
  2. 算法(sort、find...)
  3. 迭代器(容器与算法的桥梁)
  4. 仿函数(函数对象)
  5. 适配器(stack、queue...)
  6. 空间配置器(内存管理)

4. 学习 STL 的三个境界

  • 第一层:能用
  • 第二层:明理(原理、实现)
  • 第三层:能扩展

参考:《The C++ Standard Library》


二、面试题 1:二叉树按层打印(JZ78)

https://www.nowcoder.com/practice/445c44d982d04483b04a54f298796288?tpId=13

题目描述

从上到下按层打印二叉树,同一层从左到右,每一层输出一行。

思路

  • 使用 BFS + 队列
  • 每次处理一整层(根据队列当前长度)

代码实现(C++)

cpp 复制代码
class Solution {
public:
    vector<vector<int>> Print(TreeNode* pRoot) {
        vector<vector<int>> res;
        if (!pRoot) return res;
        queue<TreeNode*> q;
        q.push(pRoot);
        while (!q.empty()) {
            int size = q.size();
            vector<int> level;
            for (int i = 0; i < size; ++i) {
                TreeNode* node = q.front(); q.pop();
                level.push_back(node->val);
                if (node->left) q.push(node->left);
                if (node->right) q.push(node->right);
            }
            res.push_back(level);
        }
        return res;
    }
};

复杂度

  • 时间:O(n)
  • 空间:O(n)

三、面试题 2:重建二叉树(JZ7)

https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13

题目描述

根据前序遍历 + 中序遍历(无重复值)重建二叉树。

思路(递归)

  • 前序第一个 = 根节点
  • 中序中根节点左边 = 左子树,右边 = 右子树
  • 递归构建左右子树

代码实现(C++)

cpp 复制代码
class Solution {
public:
    TreeNode* reConstructBinaryTree(vector<int> pre, vector<int> vin) {
        if (pre.empty()) return nullptr;
        TreeNode* root = new TreeNode(pre[0]);
        int pos = 0;
        while (vin[pos] != pre[0]) ++pos;
        vector<int> leftPre(pre.begin() + 1, pre.begin() + 1 + pos);
        vector<int> leftVin(vin.begin(), vin.begin() + pos);
        vector<int> rightPre(pre.begin() + 1 + pos, pre.end());
        vector<int> rightVin(vin.begin() + pos + 1, vin.end());
        root->left = reConstructBinaryTree(leftPre, leftVin);
        root->right = reConstructBinaryTree(rightPre, rightVin);
        return root;
    }
};

复杂度

  • 时间:O(n)
  • 空间:O(n)

四、面试题 3:用两个栈实现队列(JZ9)

https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13

题目描述

用两个栈实现队列的 push 和 pop 操作,保证 pop 时队列非空。

思路(经典"倒腾"法)

  • push:直接压入 stack1
  • pop :
    • 若 stack2 不为空,直接弹出 stack2
    • 否则将 stack1 全部倒入 stack2,再弹出 stack2

代码实现(C++)

cpp 复制代码
class Solution {
public:
    void push(int node) {
        stack1.push(node);
    }
    int pop() {
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.push(stack1.top());
                stack1.pop();
            }
        }
        int res = stack2.top();
        stack2.pop();
        return res;
    }
private:
    stack<int> stack1;
    stack<int> stack2;
};

复杂度

  • 每个元素最多入栈 2 次、出栈 2 次 → 摊还 O(1)

五、C++ / STL 面试高频问答

1. 空间配置器和智能指针的联系?

  • 都涉及内存管理,但层次不同:
    • 空间配置器:管理原始内存
    • 智能指针:管理对象生命周期

2. auto_ptr 为什么被 C++11 移除?

  • 拷贝语义破坏(转移所有权),容易误用
  • 替代:unique_ptr / shared_ptr

3. nullptr 与 NULL 的区别?

  • NULL 是 0
  • nullptr 是 std::nullptr_t 类型,更安全

4. vector 与 list 的区别

对比 vector list
底层结构 连续数组 双向链表
随机访问 O(1) O(n)
插入/删除 尾部快,中间慢 任意位置快
迭代器失效 易失效 不易失效

5. vector 扩容机制

  • 通常 1.5 或 2 倍扩容
  • 导致迭代器、引用失效

6. map 底层实现

  • 红黑树,有序
  • unordered_map 是哈希表,无序,平均 O(1)

7. 链表迭代器失效

  • 删除当前节点 → 该迭代器失效
  • 插入不影响已有迭代器

六、总结

  • STL 是 C++ 开发者的必备技能
  • 学习路径:会用 → 明理 → 扩展
  • 面试中常结合 二叉树、栈、队列、容器底层原理 一起考察

如果你正在准备 C++ 开发岗,建议把这三道题 手写 3 遍以上,并且能把 STL 容器底层讲清楚。


如果有帮助,欢迎点赞、收藏、转发~

相关推荐
huanbailu2 小时前
Qt 跨线程信号槽:connect 返回 true 但槽函数不执行的坑
开发语言·c++·qt·信号槽·跨线程·元类型
HEJOO92 小时前
C++ 虚函数表(vtable)深度解析
开发语言·c++
xailorliu3 小时前
矩阵定性-正定负定不定半正定半负定
c++·opencv·线性代数·计算机视觉·矩阵
个 人 练 习 生3 小时前
C++-----string基本使用详解
开发语言·c++·学习
朝朝辞暮i3 小时前
C++ 第 5 课:else if + 多条件判断 + && / || / !
开发语言·c++
千谦阙听3 小时前
【C++篇】:string类——常用接口、底层原理与深浅拷贝
开发语言·c++·学习·visual studio
特立独行的猫A4 小时前
c++的`std::future` 与 `std::promise` 简明教程(5分钟读完)
c++
特立独行的猫A4 小时前
C++ 异步编程:std::future 与 std::promise 详解(含 RPC 客户端实现实践)
c++·后端
All for pursuit.4 小时前
【分治-2】215.数组中的第K个最大元素
数据结构·c++·算法·leetcode
lcj25114 小时前
【C++】set和map——详细使用说明
开发语言·c++·笔记·面试