CCF GESP C++ G5核心算法模板代码集
一、初等数论相关
1. 辗转相除法(欧几里得算法)- 求最大公约数
#include <algorithm>
using namespace std;
// 迭代版(效率更高,避免栈溢出)
int gcd(int a, int b) {
a = abs(a); // 处理负数情况
b = abs(b);
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
// 递归版(代码简洁,逻辑直观)
int gcd_recursive(int a, int b) {
a = abs(a);
b = abs(b);
return b == 0 ? a : gcd_recursive(b, a % b);
}
// 扩展:求最小公倍数(基于最大公约数)
int lcm(int a, int b) {
if (a == 0 || b == 0) return 0; // 避免除以零
return a / gcd(a, b) * b; // 先除后乘,避免溢出
}
2. 素数判断(高效版)
#include <cmath>
using namespace std;
bool is_prime(int num) {
if (num < 2) return false; // 小于2的数不是素数
if (num == 2 || num == 3) return true; // 2和3是素数
if (num % 2 == 0 || num % 3 == 0) return false; // 排除偶数和3的倍数
int end = sqrt(num) + 1;
// 仅遍历6k±1形式的数,优化效率
for (int i = 5; i <= end; i += 6) {
if (num % i == 0 || num % (i + 2) == 0) {
return false;
}
}
return true;
}
3. 质因数分解(唯一分解定理应用)
#include <vector>
#include <cmath>
using namespace std;
// 返回质因数及其指数对(如12返回[(2,2), (3,1)])
vector<pair<int, int>> prime_factorization(int n) {
vector<pair<int, int>> factors;
if (n <= 1) return factors;
// 处理2的因子
int cnt = 0;
while (n % 2 == 0) {
cnt++;
n /= 2;
}
if (cnt > 0) {
factors.emplace_back(2, cnt);
}
// 处理奇数因子
for (int i = 3; i <= sqrt(n); i += 2) {
cnt = 0;
while (n % i == 0) {
cnt++;
n /= i;
}
if (cnt > 0) {
factors.emplace_back(i, cnt);
}
}
// 剩余的n为素数
if (n > 2) {
factors.emplace_back(n, 1);
}
return factors;
}
4. 埃拉托斯特尼筛法(生成素数表)
#include <vector>
using namespace std;
// 生成[2, n]范围内的素数表
vector<bool> sieve_Eratosthenes(int n) {
vector<bool> is_prime(n + 1, true);
if (n >= 0) is_prime[0] = false;
if (n >= 1) is_prime[1] = false;
for (int i = 2; i * i <= n; ++i) {
if (is_prime[i]) {
// 从i*i开始标记,优化效率(小于i*i的倍数已被标记)
for (int j = i * i; j <= n; j += i) {
is_prime[j] = false;
}
}
}
return is_prime;
}
5. 线性筛法(欧拉筛)- 高效生成素数表
#include <vector>
using namespace std;
// 生成[2, n]范围内的素数表,每个合数仅被最小质因子标记
vector<int> sieve_linear(int n) {
vector<bool> is_prime(n + 1, true);
vector<int> primes;
if (n >= 0) is_prime[0] = false;
if (n >= 1) is_prime[1] = false;
for (int i = 2; i <= n; ++i) {
if (is_prime[i]) {
primes.push_back(i);
}
// 遍历已找到的素数,标记i*primes[j]为合数
for (int j = 0; j < primes.size() && 1LL * i * primes[j] <= n; ++j) {
is_prime[i * primes[j]] = false;
if (i % primes[j] == 0) {
break; // 保证每个合数仅被最小质因子标记
}
}
}
return primes;
}
二、高精度运算(数组模拟)
1. 高精度加法(支持大整数相加)
#include <vector>
#include <algorithm>
using namespace std;
// a和b为逆序存储的大整数(如123存储为[3,2,1])
vector<int> high_precision_add(vector<int> a, vector<int> b) {
vector<int> res;
int carry = 0;
int i = 0;
// 逐位相加,处理进位
while (i < a.size() || i < b.size() || carry > 0) {
int sum = carry;
if (i < a.size()) sum += a[i];
if (i < b.size()) sum += b[i];
res.push_back(sum % 10); // 存储当前位
carry = sum / 10; // 更新进位
i++;
}
return res;
}
// 辅助函数:将字符串转换为逆序数组
vector<int> str_to_rev_arr(string s) {
vector<int> res;
for (int i = s.size() - 1; i >= 0; --i) {
res.push_back(s[i] - '0');
}
return res;
}
// 辅助函数:将逆序数组转换为字符串
string rev_arr_to_str(vector<int> arr) {
string res;
// 去除前导零(逆序存储的末尾零)
while (arr.size() > 1 && arr.back() == 0) {
arr.pop_back();
}
for (int i = arr.size() - 1; i >= 0; --i) {
res.push_back(arr[i] + '0');
}
return res;
}
2. 高精度减法(支持大整数相减,a >= b)
#include <vector>
#include <algorithm>
using namespace std;
// a和b为逆序存储,且a表示的数 >= b表示的数
vector<int> high_precision_sub(vector<int> a, vector<int> b) {
vector<int> res;
int borrow = 0;
int i = 0;
while (i < a.size() || i < b.size()) {
int sub = a[i] - borrow;
if (i < b.size()) sub -= b[i];
if (sub < 0) {
sub += 10;
borrow = 1;
} else {
borrow = 0;
}
res.push_back(sub);
i++;
}
// 去除前导零
while (res.size() > 1 && res.back() == 0) {
res.pop_back();
}
return res;
}
3. 高精度乘法(大整数 × 小整数)
#include <vector>
using namespace std;
// a为逆序存储的大整数,b为小整数(int范围)
vector<int> high_precision_mul_small(vector<int> a, int b) {
vector<int> res;
int carry = 0;
for (int i = 0; i < a.size() || carry > 0; ++i) {
long long product = carry;
if (i < a.size()) product += 1LL * a[i] * b; // 避免溢出
res.push_back(product % 10);
carry = product / 10;
}
// 去除前导零
while (res.size() > 1 && res.back() == 0) {
res.pop_back();
}
return res;
}
4. 高精度除法(大整数 ÷ 小整数)
#include <vector>
#include <algorithm>
using namespace std;
// a为逆序存储的大整数,b为小整数(int范围),返回(商, 余数)
pair<vector<int>, int> high_precision_div_small(vector<int> a, int b) {
vector<int> quotient;
int remainder = 0;
// 正序遍历(从高位到低位)
for (int i = a.size() - 1; i >= 0; --i) {
long long dividend = 1LL * remainder * 10 + a[i];
quotient.push_back(dividend / b);
remainder = dividend % b;
}
// 逆序得到正确的商(因为quotient当前是正序存储)
reverse(quotient.begin(), quotient.end());
// 去除前导零
while (quotient.size() > 1 && quotient.back() == 0) {
quotient.pop_back();
}
return {quotient, remainder};
}
三、链表操作
1. 单链表结构体定义与基本操作
#include <iostream>
#include <string>
using namespace std;
// 单链表节点结构体
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode* nxt) : val(x), next(nxt) {}
};
// 插入节点到链表头部
ListNode* insert_head(ListNode* head, int val) {
ListNode* new_node = new ListNode(val);
new_node->next = head;
return new_node;
}
// 插入节点到链表尾部
ListNode* insert_tail(ListNode* head, int val) {
ListNode* new_node = new ListNode(val);
if (head == nullptr) {
return new_node;
}
ListNode* curr = head;
while (curr->next != nullptr) {
curr = curr->next;
}
curr->next = new_node;
return head;
}
// 删除链表中所有值为val的节点(含虚拟头节点优化)
ListNode* remove_elements(ListNode* head, int val) {
ListNode* dummy = new ListNode(0); // 虚拟头节点,统一处理头节点
dummy->next = head;
ListNode* curr = dummy;
while (curr->next != nullptr) {
if (curr->next->val == val) {
ListNode* temp = curr->next;
curr->next = curr->next->next;
delete temp; // 释放内存
} else {
curr = curr->next;
}
}
ListNode* new_head = dummy->next;
delete dummy; // 释放虚拟头节点
return new_head;
}
// 遍历链表并打印
void traverse_list(ListNode* head) {
ListNode* curr = head;
while (curr != nullptr) {
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
}
// 释放链表内存
void free_list(ListNode* head) {
ListNode* curr = head;
while (curr != nullptr) {
ListNode* temp = curr;
curr = curr->next;
delete temp;
}
}
2. 双链表结构体定义与基本操作
#include <iostream>
using namespace std;
// 双链表节点结构体
struct DoublyListNode {
int val;
DoublyListNode* prev;
DoublyListNode* next;
DoublyListNode(int x) : val(x), prev(nullptr), next(nullptr) {}
};
// 在节点p之后插入节点s
void insert_after(DoublyListNode* p, int val) {
if (p == nullptr) return;
DoublyListNode* s = new DoublyListNode(val);
s->next = p->next;
s->prev = p;
if (p->next != nullptr) {
p->next->prev = s;
}
p->next = s;
}
// 删除节点p(p非空)
void delete_node(DoublyListNode*& head, DoublyListNode* p) {
if (p == nullptr) return;
if (p->prev != nullptr) {
p->prev->next = p->next;
} else {
head = p->next; // p是头节点
}
if (p->next != nullptr) {
p->next->prev = p->prev;
}
delete p;
}
// 遍历双链表(正序)
void traverse_doubly_list(DoublyListNode* head) {
DoublyListNode* curr = head;
while (curr != nullptr) {
cout << curr->val << " ";
curr = curr->next;
}
cout << endl;
}
3. 循环链表判断(Floyd快慢指针法)
#include <iostream>
using namespace std;
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
// 判断单链表是否有环
bool has_cycle(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return false;
}
ListNode* slow = head;
ListNode* fast = head->next;
while (fast != nullptr && fast->next != nullptr) {
if (slow == fast) {
return true; // 快慢指针相遇,存在环
}
slow = slow->next; // 慢指针走1步
fast = fast->next->next;// 快指针走2步
}
return false; // 快指针到达终点,无环
}
四、查找算法
1. 二分查找(有序数组查找目标值)
#include <vector>
using namespace std;
// 迭代版:在有序数组nums中查找target,返回索引(-1表示未找到)
int binary_search(vector<int>& nums, int target) {
int left = 0;
int 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;
}
// 递归版:在[left, right]区间查找
int binary_search_recursive(vector<int>& nums, int target, int left, int right) {
if (left > right) return -1;
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
return binary_search_recursive(nums, target, mid + 1, right);
} else {
return binary_search_recursive(nums, target, left, mid - 1);
}
}
// 扩展:查找目标值的左边界(存在重复元素)
int find_left_bound(vector<int>& nums, int target) {
int left = 0;
int right = nums.size() - 1;
int res = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
res = mid;
right = mid - 1; // 继续向左查找左边界
} else if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return res;
}
2. 二分答案(查找满足条件的最值)
#include <vector>
using namespace std;
// 示例:在有序数组中查找大于等于target的最小元素
int binary_answer(vector<int>& nums, int target) {
int left = 0;
int right = nums.size(); // 右边界为n,处理所有元素都小于target的情况
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] >= target) {
right = mid;
} else {
left = mid + 1;
}
}
return left < nums.size() ? nums[left] : -1; // 不存在返回-1
}
五、排序算法
1. 归并排序(稳定排序,O(n log n))
#include <vector>
using namespace std;
// 合并两个有序子数组[left, mid]和[mid+1, right]
void merge(vector<int>& arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
vector<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 merge_sort(vector<int>& arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2; // 避免溢出
merge_sort(arr, left, mid); // 左子数组排序
merge_sort(arr, mid + 1, right); // 右子数组排序
merge(arr, left, mid, right); // 合并两个有序子数组
}
}
2. 快速排序(不稳定排序,平均O(n log n))
#include <vector>
#include <algorithm>
using namespace std;
// 分区函数:返回基准元素的最终位置
int partition(vector<int>& arr, int low, int high) {
int pivot = arr[high]; // 选择最右侧元素作为基准
int i = low - 1; // i指向小于基准区域的末尾
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 quick_sort(vector<int>& arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high); // 分区
quick_sort(arr, low, pi - 1); // 左子数组排序
quick_sort(arr, pi + 1, high); // 右子数组排序
}
}
// 扩展:随机选择基准,优化有序数组的情况
int random_partition(vector<int>& arr, int low, int high) {
int rand_idx = low + rand() % (high - low + 1); // 随机选择基准索引
swap(arr[rand_idx], arr[high]); // 基准移到末尾
return partition(arr, low, high);
}
void quick_sort_optimized(vector<int>& arr, int low, int high) {
if (low < high) {
int pi = random_partition(arr, low, high);
quick_sort_optimized(arr, low, pi - 1);
quick_sort_optimized(arr, pi + 1, high);
}
}
六、贪心算法
1. 活动安排问题(最多不重叠活动)
#include <vector>
#include <algorithm>
using namespace std;
// 活动结构体:start为开始时间,end为结束时间
struct Activity {
int start;
int end;
};
// 按结束时间升序排序(贪心选择核心)
bool cmp(Activity a, Activity b) {
return a.end < b.end;
}
// 选择最多不重叠的活动,返回最大活动数
int max_activities(vector<Activity>& activities) {
if (activities.empty()) return 0;
sort(activities.begin(), activities.end(), cmp);
int count = 1;
int last_end = activities[0].end;
for (int i = 1; i < activities.size(); ++i) {
// 下一个活动的开始时间 >= 上一个活动的结束时间,选择该活动
if (activities[i].start >= last_end) {
count++;
last_end = activities[i].end;
}
}
return count;
}
2. 硬币找零问题(最少硬币数)
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAX_COINS = 10;
int result[MAX_COINS] = {0}; // 存储每种硬币的使用数量
// 贪心策略:优先使用大面值硬币
int find_min_coins(vector<int>& coins, int amount) {
sort(coins.begin(), coins.end(), greater<int>()); // 硬币面值从大到小排序
int n = coins.size();
int total = 0; // 总硬币数
for (int i = 0; i < n; ++i) {
if (amount <= 0) break;
int num = amount / coins[i]; // 当前面值最多使用的数量
result[i] = num;
total += num;
amount -= num * coins[i]; // 剩余金额
}
return amount == 0 ? total : -1; // 无法找零返回-1
}
// 输出找零方案
void print_coins(vector<int>& coins) {
cout << "找零方案:" << endl;
for (int i = 0; i < coins.size(); ++i) {
if (result[i] > 0) {
cout << coins[i] << "元:" << result[i] << "枚" << endl;
}
}
}
3. 巧夺大奖(最大化游戏奖励)
#include <vector>
#include <algorithm>
using namespace std;
struct Game {
int deadline; // 完成期限
int reward; // 奖励
};
// 按奖励从大到小排序(优先选择高奖励游戏)
bool game_cmp(Game a, Game b) {
return a.reward > b.reward;
}
// 最大化获得的奖励,n为游戏数量(同时也是时间段数量)
int max_game_reward(vector<Game>& games, int n) {
sort(games.begin(), games.end(), game_cmp);
vector<bool> used(n, false); // 标记时间段是否被使用
int total = 0;
for (auto& game : games) {
// 从最后期限往前找可用时间段
for (int t = min(game.deadline - 1, n - 1); t >= 0; --t) {
if (!used[t]) {
used[t] = true;
total += game.reward;
break;
}
}
}
return total;
}
4. 分糖果问题(每个孩子至少1颗,评分高的孩子分更多)
#include <vector>
#include <algorithm>
using namespace std;
// 贪心策略:左右两次遍历,保证相邻评分高的孩子糖果更多
int candy(vector<int>& ratings) {
int n = ratings.size();
vector<int> candies(n, 1); // 每个孩子至少1颗
// 从左到右:右边评分高的比左边多1颗
for (int i = 1; i < n; ++i) {
if (ratings[i] > ratings[i-1]) {
candies[i] = candies[i-1] + 1;
}
}
// 从右到左:左边评分高的比右边多1颗(取最大值保证两边都满足)
for (int i = n-2; i >= 0; --i) {
if (ratings[i] > ratings[i+1]) {
candies[i] = max(candies[i], candies[i+1] + 1);
}
}
// 计算总糖果数
int total = 0;
for (int c : candies) total += c;
return total;
}
七、分治算法(归并排序和快速排序)
1. 归并排序(稳定排序,O(n log n))
#include <vector>
using namespace std;
// 合并两个有序子数组[left, mid]和[mid+1, right]
void merge(vector<int>& arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
vector<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 merge_sort(vector<int>& arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2; // 避免溢出
merge_sort(arr, left, mid); // 左子数组排序
merge_sort(arr, mid + 1, right); // 右子数组排序
merge(arr, left, mid, right); // 合并两个有序子数组
}
}
2. 快速排序(不稳定排序,平均O(n log n))
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>
using namespace std;
// 分区函数:选择最右侧元素作为基准,返回基准的最终位置
int partition(vector<int>& arr, int low, int high) {
int pivot = arr[high]; // 基准元素
int i = low - 1; // i指向小于基准区域的末尾
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;
}
// 随机分区(优化有序数组的最坏情况)
int random_partition(vector<int>& arr, int low, int high) {
srand((unsigned int)time(NULL));
int rand_idx = low + rand() % (high - low + 1); // 随机选择基准索引
swap(arr[rand_idx], arr[high]); // 基准移到末尾
return partition(arr, low, high);
}
// 快速排序主函数(优化版)
void quick_sort(vector<int>& arr, int low, int high) {
if (low < high) {
int pi = random_partition(arr, low, high); // 分区
quick_sort(arr, low, pi - 1); // 左子数组排序
quick_sort(arr, pi + 1, high); // 右子数组排序
}
}
3. 最大子数组和(分治实现,O(n log n))
#include <vector>
#include <climits>
#include <algorithm>
using namespace std;
// 计算跨中间点的最大子数组和
int cross_max(vector<int>& nums, int left, int mid, int right) {
// 左半部分最大和(从mid向左扩展)
int left_max = INT_MIN;
int sum = 0;
for (int i = mid; i >= left; --i) {
sum += nums[i];
left_max = max(left_max, sum);
}
// 右半部分最大和(从mid+1向右扩展)
int right_max = INT_MIN;
sum = 0;
for (int i = mid + 1; i <= right; ++i) {
sum += nums[i];
right_max = max(right_max, sum);
}
return left_max + right_max;
}
// 分治求解最大子数组和
int max_subarray(vector<int>& nums, int left, int right) {
if (left == right) return nums[left]; // 递归终止条件:单个元素
int mid = left + (right - left) / 2;
int left_max = max_subarray(nums, left, mid); // 左子数组最大和
int right_max = max_subarray(nums, mid + 1, right); // 右子数组最大和
int cross = cross_max(nums, left, mid, right); // 跨中间点最大和
return max({left_max, right_max, cross}); // 返回三者最大值
}
// 对外接口
int max_subarray_sum(vector<int>& nums) {
if (nums.empty()) return 0;
return max_subarray(nums, 0, nums.size() - 1);
}
八、递归算法
1. 斐波那契数列(递归+记忆化优化)
#include <vector>
using namespace std;
// 记忆化递归:避免重复计算
long long fib_memo(int n, vector<long long>& memo) {
if (n <= 1) return n;
if (memo[n] != -1) return memo[n]; // 已计算过直接返回
memo[n] = fib_memo(n - 1, memo) + fib_memo(n - 2, memo);
return memo[n];
}
// 对外接口
long long fibonacci(int n) {
if (n < 0) return 0;
vector<long long> memo(n + 1, -1); // 记忆化数组
return fib_memo(n, memo);
}
2. 汉诺塔问题(递归实现)
#include <iostream>
#include <string>
using namespace std;
// 将n个圆盘从A柱通过B柱移动到C柱
void hanoi(string A, string B, string C, int n) {
if (n == 1) {
// 递归终止:1个圆盘直接移动
cout << A << "->" << C << endl;
return;
}
hanoi(A, C, B, n - 1); // 把n-1个圆盘从A移到B(借助C)
cout << A << "->" << C << endl; // 把第n个圆盘从A移到C
hanoi(B, A, C, n - 1); // 把n-1个圆盘从B移到C(借助A)
}
3. 字符串反转(递归实现)
#include <string>
using namespace std;
string reverse_string(string s) {
if (s.length() <= 1) return s; // 递归终止:空串或单个字符
// 取最后一个字符 + 剩余子串的反转
return s.back() + reverse_string(s.substr(0, s.length() - 1));
}
4. 阶乘计算(递归实现)
// 递归计算n的阶乘(n >= 0)
long long factorial(int n) {
if (n == 0 || n == 1) return 1; // 递归终止条件
return n * factorial(n - 1); // 递归表达式
}
九、算法复杂度相关(辅助工具)
1. 复杂度估算辅助函数(统计基本操作次数)
#include <iostream>
using namespace std;
// 统计冒泡排序的基本操作次数(交换+比较)
pair<int, int> bubble_sort_count(vector<int>& arr) {
int n = arr.size();
int compare_cnt = 0; // 比较次数
int swap_cnt = 0; // 交换次数
for (int i = 0; i < n - 1; ++i) {
bool flag = false;
for (int j = 0; j < n - 1 - i; ++j) {
compare_cnt++;
if (arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
swap_cnt++;
flag = true;
}
}
if (!flag) break; // 无交换说明已有序
}
return {compare_cnt, swap_cnt};
}
// 统计二分查找的比较次数
int binary_search_count(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
int compare_cnt = 0;
while (left <= right) {
compare_cnt++;
int mid = left + (right - left) / 2;
if (nums[mid] == target) return compare_cnt;
else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return compare_cnt; // 未找到也返回比较次数
}
2. 常见复杂度对比工具(生成测试数据)
#include <vector>
#include <random>
using namespace std;
// 生成随机数组
vector<int> generate_random_array(int n, int min_val, int max_val) {
vector<int> arr(n);
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(min_val, max_val);
for (int i = 0; i < n; ++i) {
arr[i] = dis(gen);
}
return arr;
}
// 生成有序数组(升序)
vector<int> generate_sorted_array(int n, int start = 1) {
vector<int> arr(n);
for (int i = 0; i < n; ++i) {
arr[i] = start + i;
}
return arr;
}
// 生成逆序数组
vector<int> generate_reverse_sorted_array(int n, int end = 1000) {
vector<int> arr(n);
for (int i = 0; i < n; ++i) {
arr[i] = end - i;
}
return arr;
}