更新中:C++ STL库,查找排序(基础算法),数据结构,数学算法,竞赛相关基础

目录

[楔子:C++ STL](#楔子:C++ STL)

[1.Vector 动态数组:](#1.Vector 动态数组:)

[2.Stack 栈:](#2.Stack 栈:)

[3.Queue 队列:](#3.Queue 队列:)

[4.Deque 双端队列:](#4.Deque 双端队列:)

[5.Map 映射:](#5.Map 映射:)

[6.Set 集合:](#6.Set 集合:)

[7.Pair 二元组:](#7.Pair 二元组:)

[8.String 字符串:](#8.String 字符串:)

[9.Array 数组:](#9.Array 数组:)

[10.Tuple 元组:](#10.Tuple 元组:)

一、基础算法

排序:

1.冒泡排序

2.选择排序

3.插入排序

4.快速排序

5.归并排序

6.计数排序(特定场景)

7.基数排序(特定场景)

二、数据结构相关算法

三、数学相关算法

四、高级算法

五、算法优化

六、实际应用(结合业务场景设计算法)


楔子:C++ STL

STL = Standard Template Library(标准模板库)

可以理解为 C++ 自带的"工具箱",里面装好了常用的数据结构和算法,直接拿来用就行,不用自己从头写。

1.Vector 动态数组:

可变长数组,可以随时添加数值和删除元素。

cpp 复制代码
#include<iostream>
#include<vector>
using namespace std;
int main() {
    vector<int> v[3];
    v[0].push_back(1);
    v[0].push_back(1);
    v[0].push_back(1);

    v[1].push_back(2);

    v[2].push_back(3);
    v[2].push_back(3);
    for(int i=0;i<3;i++) {
        for(int j=0;j<v[i].size();j++) {
            cout<<v[i][j]<<" ";
        }
        cout<<endl;
    }
}

2.Stack 栈:

先进后出,后进先出的容器。

cpp 复制代码
#include<iostream>
#include<stack>
using namespace std;

int main() {
    stack<int> st;
    st.push(10);
    st.push(20);
    st.push(30);

    while (!st.empty()) {
        int val_top = st.top();
        cout<<val_top<<endl;
        st.pop();
    }
}

3.Queue 队列:

先进先出的容器。

cpp 复制代码
#include<iostream>
#include<queue>
#include<deque> //双端队列
using namespace std;

int main() {
    queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    while (!q.empty()) {
        cout << q.front() << endl;
        q.pop();
    }
}

4.Deque 双端队列:

首尾都可插入和删除的队列为双端队列。

cpp 复制代码
#include<iostream>
#include<queue>
#include<deque> //双端队列
using namespace std;

int main() {
    queue<int> q;
    q.push(10);
    q.push(20);
    q.push(30);

    while (!q.empty()) {
        cout << q.front() << endl;
        q.pop();
    }
}

5.Map 映射:

每个x对应一个y,而map是每个键对应一个值,与python的字典类型相似。

cpp 复制代码
#include<iostream>
#include<map>
using namespace std;

int main() {
    map<string,int> mp;

    mp["apple"] = 4;
    mp["banana"] = 3;
    mp["coconut"] = 5;

    for (auto i:mp) {
        cout<<i.first<<" = "<<i.second<<endl;
    }
}

6.Set 集合:

集合,元素不会重复,set容器里的元素自动从小到大排序。

cpp 复制代码
#include<iostream>
#include<set>
using namespace std;

int main() {
    set<int> s{8,8,58,2};//自动升序且去重
    for (auto i:s) {
        cout<<i<<" ";
    }
}

7.Pair 二元组:

pair只含有两个元素,可以看作是只有两个元素的结构体。

cpp 复制代码
#include <iostream>
using namespace std;

int main() {
    // 最简洁的初始化
    pair<int, int> p = {1, 2};
    // pair 数组
    pair<int, int> arr[3] = {{1, 2}, {3, 4}, {5, 6}};

    // 打印
    cout << p.first << " " << p.second << endl;  // 输出:1 2
    // 遍历打印
    for (auto i : arr) {
        cout << i.first << "," << i.second<<"   ";
    }

    return 0;
}

8.String 字符串:

字符串类。

cpp 复制代码
#include<iostream>
#include<string>
using namespace std;

int main() {
    略;
}

9.Array 数组:

Array是C++ 11新增的容器,比vector效率要高。

cpp 复制代码
#include<iostream>
#include<array>
using namespace std;

int main() {
    array<int,5> arr{1,2,3,4,5};//一开始就固定
    for (auto i : arr) {
        cout << i << endl;
    }
}

10.Tuple 元组:

可以把tuple理解为pair的扩展,tuple可以声明二元组,也可以声明三元组。

cpp 复制代码
#include<iostream>
#include<tuple>
using namespace std;

int main() {
    tuple<int,double,string> t{3,0.14,"Pi"};
    //只能用get访问d
    cout<<get<0>(t)<<endl;
    cout<<get<1>(t)<<endl;
    cout<<get<2>(t)<<endl;
}

一、基础算法(排序、查找)

排序:

1.冒泡排序

cpp 复制代码
#include <iostream>
using namespace std;

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // 交换
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    bubbleSort(arr, n);
    
    cout << "排序后: ";
    for (int i = 0; i < n; i++) {
        cout << arr[i] << " ";
    }
    cout << endl;
    
    return 0;
}

2.选择排序

cpp 复制代码
#include <iostream>
using namespace std;

void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIdx = i;  // 假设当前 i 是最小值的位置
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIdx]) {
                minIdx = j;  // 找到更小的,更新位置
            }
        }
        // 交换
        swap(arr[i], arr[minIdx]);
    }
}

int main() {
    int arr[] = {64, 25, 12, 22, 11};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    selectionSort(arr, n);
    
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    return 0;
}

3.插入排序

cpp 复制代码
#include <iostream>
using namespace std;

void insertionSort(int arr[], int n) {
    for (int i = 1; i < n; i++) {
        int key = arr[i];  // 当前要插入的元素
        int j = i - 1;
        
        // 将比 key 大的元素都往后移
        while (j >= 0 && arr[j] > key) {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = key;  // 插入到正确位置
    }
}

int main() {
    int arr[] = {12, 11, 13, 5, 6};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    insertionSort(arr, n);
    
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    return 0;
}

4.快速排序

cpp 复制代码
#include <iostream>
using namespace std;

int partition(int arr[], int low, int high) {
    int pivot = arr[high];  // 选最后一个作为基准
    int i = low - 1;        // 小于基准的区域的边界
    
    for (int j = low; j < high; j++) {
        if (arr[j] <= pivot) {
            i++;
            swap(arr[i], arr[j]);
        }
    }
    swap(arr[i + 1], arr[high]);
    return i + 1;  // 返回基准的位置
}

void quickSort(int arr[], int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi - 1);
        quickSort(arr, pi + 1, high);
    }
}

int main() {
    int arr[] = {10, 7, 8, 9, 1, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    quickSort(arr, 0, n - 1);
    
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    return 0;
}

5.归并排序

cpp 复制代码
#include <iostream>
using namespace std;

void merge(int arr[], int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;
    
    // 创建临时数组
    int L[n1], R[n2];
    
    // 拷贝数据
    for (int i = 0; i < n1; i++) L[i] = arr[left + i];
    for (int j = 0; j < n2; j++) R[j] = arr[mid + 1 + j];
    
    // 合并
    int i = 0, j = 0, k = left;
    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) arr[k++] = L[i++];
        else arr[k++] = R[j++];
    }
    
    // 拷贝剩余元素
    while (i < n1) arr[k++] = L[i++];
    while (j < n2) arr[k++] = R[j++];
}

void mergeSort(int arr[], int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid + 1, right);
        merge(arr, left, mid, right);
    }
}

int main() {
    int arr[] = {12, 11, 13, 5, 6, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    mergeSort(arr, 0, n - 1);
    
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    return 0;
}

6.计数排序(特定场景)

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

void countingSort(int arr[], int n) {
    // 找到最大值和最小值
    int maxVal = arr[0], minVal = arr[0];
    for (int i = 1; i < n; i++) {
        maxVal = max(maxVal, arr[i]);
        minVal = min(minVal, arr[i]);
    }
    
    int range = maxVal - minVal + 1;
    vector<int> count(range, 0);
    
    // 统计每个数出现的次数
    for (int i = 0; i < n; i++) {
        count[arr[i] - minVal]++;
    }
    
    // 按顺序输出
    int idx = 0;
    for (int i = 0; i < range; i++) {
        while (count[i] > 0) {
            arr[idx++] = i + minVal;
            count[i]--;
        }
    }
}

int main() {
    int arr[] = {4, 2, 2, 8, 3, 3, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    countingSort(arr, n);
    
    for (int i = 0; i < n; i++) cout << arr[i] << " ";
    return 0;
}

7.基数排序(特定场景)

搜索:

1.线性搜索

cpp 复制代码
#include <iostream>
using namespace std;

int linearSearch(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target) {
            return i;  // 找到返回下标
        }
    }
    return -1;  // 没找到
}

int main() {
    int arr[] = {5, 3, 8, 6, 2, 7};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 6;
    
    int result = linearSearch(arr, n, target);
    
    if (result != -1) {
        cout << "找到了,下标是: " << result << endl;
    } else {
        cout << "没找到" << endl;
    }
    
    return 0;
}

2.二分搜索(有序数组)

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>  // 给 sort 用
using namespace std;

// 迭代版本(推荐)
int binarySearch(int arr[], int n, int target) {
    int left = 0, right = n - 1;
    
    while (left <= right) {
        int mid = left + (right - left) / 2;  // 防止溢出
        
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1;
}

// 递归版本
int binarySearchRecursive(int arr[], int left, int right, int target) {
    if (left > right) return -1;
    
    int mid = left + (right - left) / 2;
    
    if (arr[mid] == target) return mid;
    else if (arr[mid] < target) 
        return binarySearchRecursive(arr, mid + 1, right, target);
    else 
        return binarySearchRecursive(arr, left, mid - 1, target);
}

int main() {
    int arr[] = {2, 5, 6, 8, 11, 15, 20};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 11;
    
    // 二分搜索要求数组有序
    // arr 已经有序,无序的话先 sort(arr, arr + n)
    
    int result = binarySearch(arr, n, target);
    
    if (result != -1) {
        cout << "找到了,下标是: " << result << endl;
    } else {
        cout << "没找到" << endl;
    }
    
    return 0;
}

3.深度优先搜索(DFS)

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

// 用邻接表存储图
vector<vector<int>> graph;
vector<bool> visited;

// 递归 DFS
void dfsRecursive(int node) {
    visited[node] = true;
    cout << node << " ";  // 访问当前节点
    
    // 遍历所有邻居
    for (int neighbor : graph[node]) {
        if (!visited[neighbor]) {
            dfsRecursive(neighbor);
        }
    }
}

// 栈实现 DFS(非递归)
void dfsStack(int start) {
    vector<bool> visited(graph.size(), false);
    stack<int> st;
    
    st.push(start);
    
    while (!st.empty()) {
        int node = st.top();
        st.pop();
        
        if (visited[node]) continue;
        
        visited[node] = true;
        cout << node << " ";
        
        // 把邻居压入栈(逆序可以保持顺序)
        for (int neighbor : graph[node]) {
            if (!visited[neighbor]) {
                st.push(neighbor);
            }
        }
    }
}

int main() {
    // 创建图(邻接表)
    int n = 6;  // 节点数 0-5
    graph.resize(n);
    
    // 添加边(无向图)
    graph[0] = {1, 2};
    graph[1] = {0, 3, 4};
    graph[2] = {0, 4};
    graph[3] = {1, 5};
    graph[4] = {1, 2, 5};
    graph[5] = {3, 4};
    
    // DFS 遍历(从节点0开始)
    visited.assign(n, false);
    cout << "递归 DFS: ";
    dfsRecursive(0);
    cout << endl;
    
    cout << "栈 DFS: ";
    dfsStack(0);
    cout << endl;
    
    return 0;
}

4.广度优先搜索(BFS)

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

void bfs(vector<vector<int>>& graph, int start) {
    int n = graph.size();
    vector<bool> visited(n, false);
    queue<int> q;
    
    visited[start] = true;
    q.push(start);
    
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        cout << node << " ";
        
        for (int neighbor : graph[node]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                q.push(neighbor);
            }
        }
    }
}

// BFS 求最短路径(无权图)
vector<int> bfsShortestPath(vector<vector<int>>& graph, int start, int target) {
    int n = graph.size();
    vector<bool> visited(n, false);
    vector<int> prev(n, -1);  // 记录前驱节点
    queue<int> q;
    
    visited[start] = true;
    q.push(start);
    
    while (!q.empty()) {
        int node = q.front();
        q.pop();
        
        if (node == target) break;
        
        for (int neighbor : graph[node]) {
            if (!visited[neighbor]) {
                visited[neighbor] = true;
                prev[neighbor] = node;
                q.push(neighbor);
            }
        }
    }
    
    // 构建路径
    vector<int> path;
    for (int at = target; at != -1; at = prev[at]) {
        path.push_back(at);
    }
    reverse(path.begin(), path.end());
    
    return path;
}

int main() {
    // 创建图
    int n = 6;
    vector<vector<int>> graph(n);
    
    graph[0] = {1, 2};
    graph[1] = {0, 3, 4};
    graph[2] = {0, 4};
    graph[3] = {1, 5};
    graph[4] = {1, 2, 5};
    graph[5] = {3, 4};
    
    // BFS 遍历
    cout << "BFS: ";
    bfs(graph, 0);
    cout << endl;
    
    // BFS 最短路径
    vector<int> path = bfsShortestPath(graph, 0, 5);
    cout << "0 到 5 的最短路径: ";
    for (int node : path) {
        cout << node << " ";
    }
    cout << endl;
    
    return 0;
}

二、数据结构相关算法

  • 数组:遍历、插入、删除、反转、前缀和、差分数组

  • 链表:单链表(反转、合并、找环)、双向链表

  • :括号匹配、表达式求值、单调栈

  • 队列:普通队列、循环队列、双端队列、单调队列(滑动窗口)

    • 二叉树(前/中/后序遍历、层序遍历)

    • 二叉搜索树(BST)

    • 最近公共祖先(LCA)

    • 树的直径、深度计算

  • 图操作

    • 图的存储(邻接矩阵、邻接表)

    • 图的遍历(DFS、BFS)

    • 最短路径(Dijkstra、Floyd)

    • 拓扑排序、最小生成树(Kruskal、Prim)

三、数学相关算法

  • 数论

    • 最大公约数(GCD)、最小公倍数(LCM)

    • 素数判定、筛法(埃氏筛、欧拉筛)

    • 快速幂

    • 同余、模运算

  • 概率:基本概率计算、期望

  • 统计:均值、中位数、众数、方差(基础)

四、高级算法

  • 动态规划

    • 背包问题(0/1背包、完全背包)

    • 最长公共子序列(LCS)

    • 最长上升子序列(LIS)

    • 区间DP、状态压缩DP(基础)

  • 贪心:区间调度、活动选择、哈夫曼编码、最小生成树的Prim/Kruskal也是贪心

  • 分治:归并排序、快速排序、二分搜索、平面最近点对

五、算法优化

  • 复杂度分析

    • 时间复杂度(大O表示法)

    • 空间复杂度

    • 常见复杂度:O(1), O(log n), O(n), O(n log n), O(n²), O(2ⁿ)

六、实际应用(结合业务场景设计算法)

  • 模拟类问题(按照题目描述的流程写代码)

  • 字符串处理(模式匹配、编辑距离、回文)

  • 简单数据压缩/编码思想

  • 模拟现实流程(如银行排队、任务调度)

相关推荐
智者知已应修善业1 小时前
【51单片机使用IO组赋值方法实现无源蜂鸣器响时LED12亮不响时34亮】2024-3-7
c++·经验分享·笔记·算法·51单片机
.千余1 小时前
【C++】深挖STL list底层:解迭代器与节点存储逻辑
开发语言·c++·笔记·学习·其他
雪落漂泊1 小时前
C++ 继承与多态(上)
开发语言·c++
聆风吟º1 小时前
【C++11新章】列表初始化详解
开发语言·c++·列表初始化
珊瑚里的鱼1 小时前
【动态规划】按摩师
算法·动态规划
Fms_Sa1 小时前
贪心算法-背包问题
算法·贪心算法·c#
alwaysrun1 小时前
C++之灵活易用的YAML解析库yaml-cpp
c++·后端·程序员
大雨淅淅1 小时前
【机器人】ROS2 机械臂控制(MoveIt2)从入门到实战
人工智能·python·神经网络·学习·算法·机器学习·机器人
Shadow(⊙o⊙)2 小时前
进程间通信0.0-pipe()匿名管道,详细分析进程池调度队列执行逻辑,进程池模拟实现。
linux·运维·服务器·开发语言·c++