引言
算法是计算机科学的核心,也是程序员解决复杂问题的利器。从基础的排序与查找到进阶的动态规划与图论算法,掌握这些技能不仅是提升编程能力的必经之路,更是解决实际问题的根本。本篇文章将通过 C++ 实现多个经典算法,包括排序、二分查找、动态规划、深度优先搜索(DFS)与 Dijkstra 最短路径算法,助你从基础入门到进阶精通。
第一部分:基础算法篇
1.1 冒泡排序:从无序到有序的第一步
冒泡排序是一个简单的排序算法,通过不断比较相邻元素并交换位置,将较大的元素“冒泡”到右侧。
代码实现:
#include <iostream>
#include <vector>
using namespace std;
void bubbleSort(vector<int>& arr) {
int n = arr.size();
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
}
}
}
}
int main() {
vector<int> arr = {64, 34, 25, 12, 22, 11, 90};
cout << "排序前的数组: ";
for (int num : arr) cout << num << " ";
cout << endl;
bubbleSort(arr);
cout << "排序后的数组: ";
for (int num : arr) cout << num << " ";
cout << endl;
return 0;
}
1.2 二分查找:高效定位目标的秘诀
二分查找是一种高效的查找算法,适用于有序数组。通过逐步缩小查找范围,可以在 O(logn)O(logn) 的时间复杂度内定位目标值。
代码实现:
#include <iostream>
#include <vector>
using namespace std;
int binarySearch(const vector<int>& arr, int target) {
int left = 0, right = arr.size() - 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 main() {
vector<int> arr = {2, 3, 4, 10, 40};
int target = 10;
int result = binarySearch(arr, target);
if (result != -1) {
cout << "目标值 " << target << " 在索引 " << result << " 处" << endl;
} else {
cout << "目标值 " << target << " 未找到" << endl;
}
return 0;
}
第二部分:进阶算法篇
2.1 动态规划:解决 0/1 背包问题
动态规划是一种通过记录子问题结果来避免重复计算的优化算法。在 0/1 背包问题中,我们利用动态规划求解在给定背包容量下,如何选择物品以最大化价值。
代码实现:
#include <iostream>
#include <vector>
using namespace std;
int knapsack(int W, const vector<int>& weight, const vector<int>& value, int n) {
vector<vector<int>> dp(n + 1, vector<int>(W + 1, 0));
for (int i = 1; i <= n; i++) {
for (int w = 1; w <= W; w++) {
if (weight[i - 1] <= w) {
dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weight[i - 1]] + value[i - 1]);
} else {
dp[i][w] = dp[i - 1][w];
}
}
}
return dp[n][W];
}
int main() {
int W = 50;
vector<int> weight = {10, 20, 30};
vector<int> value = {60, 100, 120};
int n = weight.size();
cout << "背包的最大价值: " << knapsack(W, weight, value, n) << endl;
return 0;
}
2.2 图算法:Dijkstra 最短路径
Dijkstra 是经典的单源最短路径算法,适合无负权边的图。我们通过优先队列实现高效的路径计算。
代码实现:
#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;
const int INF = INT_MAX;
void dijkstra(int start, const vector<vector<pair<int, int>>>& graph, vector<int>& distance) {
int n = graph.size();
distance.assign(n, INF);
distance[start] = 0;
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
pq.push({0, start});
while (!pq.empty()) {
int currentDist = pq.top().first;
int currentNode = pq.top().second;
pq.pop();
if (currentDist > distance[currentNode]) continue;
for (auto& edge : graph[currentNode]) {
int nextNode = edge.first;
int weight = edge.second;
if (distance[currentNode] + weight < distance[nextNode]) {
distance[nextNode] = distance[currentNode] + weight;
pq.push({distance[nextNode], nextNode});
}
}
}
}
int main() {
int n = 5;
vector<vector<pair<int, int>>> graph(n);
graph[0].push_back({1, 10});
graph[0].push_back({4, 5});
graph[1].push_back({2, 1});
graph[2].push_back({3, 4});
graph[4].push_back({1, 3});
graph[4].push_back({2, 9});
graph[4].push_back({3, 2});
vector<int> distance;
dijkstra(0, graph, distance);
cout << "从节点 0 出发到其他节点的最短距离: " << endl;
for (int i = 0; i < distance.size(); i++) {
cout << "节点 0 到节点 " << i << " 的距离: " << (distance[i] == INF ? -1 : distance[i]) << endl;
}
return 0;
}