当前位置: 首页 > news >正文

C++算法实例精讲

C++算法实例

以下是一些难度中等的C++算法实例,涵盖常见数据结构、经典算法及实际问题解决场景,每个示例均附简要说明。


二分查找

int binarySearch(vector<int>& nums, int target) {int left = 0, right = nums.size() - 1;while (left <= right) {int mid = left + (right - left) / 2;if (nums[mid] == target) return mid;else if (nums[mid] < target) left = mid + 1;else right = mid - 1;}return -1;
}

在有序数组中高效查找目标值,时间复杂度为O(log n)。

快速排序

void quickSort(vector<int>& arr, int low, int high) {if (low < high) {int pivot = partition(arr, low, high);quickSort(arr, low, pivot - 1);quickSort(arr, pivot + 1, high);}
}int partition(vector<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) swap(arr[++i], arr[j]);}swap(arr[i + 1], arr[high]);return i + 1;
}

分治思想实现排序,平均时间复杂度O(n log n)。

链表反转

ListNode* reverseList(ListNode* head) {ListNode *prev = nullptr, *curr = head;while (curr) {ListNode* next = curr->next;curr->next = prev;prev = curr;curr = next;}return prev;
}

通过迭代修改指针方向实现链表反转。

动态规划:斐波那契数列

int fib(int n) {if (n <= 1) return n;vector<int> dp(n + 1);dp[0] = 0; dp[1] = 1;for (int i = 2; i <= n; i++) dp[i] = dp[i - 1] + dp[i - 2];return dp[n];
}

使用动态规划避免递归的重复计算。

Dijkstra最短路径算法

void dijkstra(vector<vector<pair<int, int>>>& graph, int start) {priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;vector<int> dist(graph.size(), INT_MAX);dist[start] = 0;pq.emplace(0, start);while (!pq.empty()) {auto [d, u] = pq.top(); pq.pop();if (d > dist[u]) continue;for (auto& [v, w] : graph[u]) {if (dist[v] > dist[u] + w) {dist[v] = dist[u] + w;pq.emplace(dist[v], v);}}}
}

基于优先队列实现带权图单源最短路径查找。

二叉树层序遍历

vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res;queue<TreeNode*> q;if (root) q.push(root);while (!q.empty()) {int size = q.size();vector<int> level;while (size--) {auto 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;
}

使用队列实现二叉树的广度优先遍历。

检测有向无环图依赖关系的C++实现

检测有向无环图依赖关系的C++实现

检测有向无环图(DAG)依赖关系的常见方法是拓扑排序。以下是一个完整的C++实现示例,包含图的构建、拓扑排序和依赖关系检测。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;class Graph {int V;vector<vector<int>> adj;public:Graph(int V) : V(V), adj(V) {}void addEdge(int u, int v) {adj[u].push_back(v);}vector<int> topologicalSort() {vector<int> inDegree(V, 0);for (int u = 0; u < V; ++u) {for (int v : adj[u]) {inDegree[v]++;}}queue<int> q;for (int u = 0; u < V; ++u) {if (inDegree[u] == 0) {q.push(u);}}vector<int> result;while (!q.empty()) {int u = q.front();q.pop();result.push_back(u);for (int v : adj[u]) {if (--inDegree[v] == 0) {q.push(v);}}}if (result.size() != V) {return {}; // 存在环}return result;}bool hasCycle() {return topologicalSort().empty();}void printDependencies() {auto order = topologicalSort();if (order.empty()) {cout << "Graph contains a cycle!" << endl;return;}cout << "Dependency order: ";for (int u : order) {cout << u << " ";}cout << endl;cout << "Detailed dependencies:" << endl;for (int u : order) {if (!adj[u].empty()) {cout << u << " depends on: ";for (int v : adj[u]) {cout << v << " ";}cout << endl;}}}
};

DAG依赖关系测试用例

以下是30个不同结构的DAG测试用例,可用于验证上述实现:

  1. 简单线性依赖
Graph g1(3);
g1.addEdge(0, 1);
g1.addEdge(1, 2);
g1.printDependencies();

  1. 多分支无交叉
Graph g2(4);
g2.addEdge(0, 1);
g2.addEdge(0, 2);
g2.addEdge(1, 3);
g2.printDependencies();

  1. 多分支有交叉
Graph g3(5);
g3.addEdge(0, 1);
g3.addEdge(0, 2);
g3.addEdge(1, 3);
g3.addEdge(2, 3);
g3.addEdge(3, 4);
g3.printDependencies();

  1. 多入口点
Graph g4(6);
g4.addEdge(0, 2);
g4.addEdge(1, 2);
g4.addEdge(2, 3);
g4.addEdge(3, 4);
g4.addEdge(3, 5);
g4.printDependencies();

  1. 复杂依赖网
Graph g5(7);
g5.addEdge(0, 1);
g5.addEdge(0, 2);
g5.addEdge(1, 3);
g5.addEdge(2, 3);
g5.addEdge(3, 4);
g5.addEdge(3, 5);
g5.addEdge(4, 6);
g5.addEdge(5, 6);
g5.printDependencies();

6-30. 其他测试用例模式(可根据需要扩展):

  • 星型依赖结构
  • 树形依赖结构
  • 网格状依赖
  • 分层依赖结构
  • 随机生成的有效DAG
  • 包含孤立节点的图
  • 所有节点相互独立的图
  • 单节点自环(应检测为环)
  • 简单环(两个节点互依赖)
  • 复杂环结构

环检测验证

以下是一些包含环的测试用例,用于验证环检测功能:

// 简单环
Graph cycle1(2);
cycle1.addEdge(0, 1);
cycle1.addEdge(1, 0);
cycle1.printDependencies();// 大环
Graph cycle2(5);
cycle2.addEdge(0, 1);
cycle2.addEdge(1, 2);
cycle2.addEdge(2, 3);
cycle2.addEdge(3, 4);
cycle2.addEdge(4, 0);
cycle2.printDependencies();// 局部环
Graph cycle3(6);
cycle3.addEdge(0, 1);
cycle3.addEdge(1, 2);
cycle3.addEdge(2, 3);
cycle3.addEdge(3, 1); // 形成局部环
cycle3.addEdge(2, 4);
cycle3.addEdge(4, 5);
cycle3.printDependencies();

实际应用示例

构建任务调度系统依赖关系检测:

Graph taskGraph(8);
// 任务0: 无依赖
taskGraph.addEdge(1, 0); // 任务1依赖任务0
taskGraph.addEdge(2, 0);
taskGraph.addEdge(3, 1);
taskGraph.addEdge(3, 2);
taskGraph.addEdge(4, 3);
taskGraph.addEdge(5, 3);
taskGraph.addEdge(6, 4);
taskGraph.addEdge(6, 5);
taskGraph.addEdge(7, 6);
taskGraph.printDependencies();

性能优化建议

对于大规模图,可以考虑以下优化:

  • 使用邻接表存储图结构
  • 实现并行拓扑排序算法
  • 使用更高效的数据结构如Fibonacci堆
  • 对静态图进行预处理

可视化建议

为了更好地理解依赖关系,可以:

  1. 将拓扑排序结果图形化展示
  2. 使用Graphviz生成DOT格式的依赖图
  3. 实现不同颜色标记关键路径
  4. 高亮显示循环依赖(如果存在)

以上实现和测试用例涵盖了DAG依赖关系检测的主要场景,可根据具体需求进行调整和扩展。

KMP算法

KMP算法简介

KMP算法(Knuth-Morris-Pratt)是一种高效的字符串匹配算法,通过预处理模式串生成部分匹配表(next数组),避免主串回溯,将时间复杂度优化至O(n+m)。

核心实现步骤

1. 构建next数组
next数组记录模式串前缀与后缀的最长公共长度,用于匹配失败时快速跳转。

vector<int> buildNext(const string& pattern) {vector<int> next(pattern.size(), 0);int j = 0;for (int i = 1; i < pattern.size(); ) {if (pattern[i] == pattern[j]) {next[i++] = ++j;} else {if (j != 0) j = next[j-1];else next[i++] = 0;}}return next;
}

2. 匹配过程
利用next数组跳过不必要的比较:

int kmpSearch(const string& text, const string& pattern) {vector<int> next = buildNext(pattern);int i = 0, j = 0;while (i < text.size() && j < pattern.size()) {if (text[i] == pattern[j]) {
http://www.dtcms.com/a/303608.html

相关文章:

  • MKS E28H 0.05-100 Torr 加热 (100°C) Baratron 电容压力计,带蚀刻传感器 手侧
  • C++入门自学Day2-- c++类与对象(初识2)
  • 一文理清 Linux 软件管理核心知识:从程序组成到包管理工具
  • C语言中的数据结构--栈和队列(2)
  • VMware Workstation Pro 详细安装步骤
  • 线程安全
  • C++常见的仿函数,预定义函数,functor,二元操作函数(对vector操作,加减乘除取余位运算等 )
  • 异步通讯组件MQ
  • HTML应用指南:利用GET请求获取全国小米之家门店位置信息
  • 基于深度学习的医学图像分析:使用3D CNN实现肿瘤检测
  • hot100——第九周
  • 在Linux上使用DuckCP实现从csv文件汇总数据到SQLite数据库的表
  • 数据开源 | “白虎”数据集首批开源,迈出百万数据征途第一步
  • Zynq SOC FPGA嵌入式裸机设计和开发教程自学笔记:硬件编程原理、基于SDK库函数编程、软件固化
  • 2.DRF 序列化器-Serializer
  • 第五章:进入Redis的Hash核心
  • 小架构step系列28:自定义校验注解
  • 【算法训练营Day17】二叉树part7
  • 【VASP】二维材料杨氏模量与泊松比的公式
  • OpenLayers 综合案例-信息窗体-弹窗
  • 打卡day5
  • C++面试5题--5day
  • C++中的“对象切片“:一场被截断的继承之痛
  • 【SpringMVC】MVC中Controller的配置 、RestFul的使用、页面重定向和转发
  • rhel9.1配置本地源并设置开机自动挂载(适用于物理光驱的场景)
  • c++ 基础
  • windows内核研究(异常-CPU异常记录)
  • 嵌入式分享合集186
  • STM32时钟源
  • JavaScript手录09-内置对象【String对象】