c++oding="utf-8" ?>
中位数必须先排序才能正确计算;c++中需用std::sort对vector升序排序,奇数长度取中间元素,偶数长度取中间两元素平均值并转double避免整除。

中位数计算前必须排序
中位数定义依赖于有序序列,C++ 原生数组不自带排序能力,直接对未排序数组取中间元素是错的。哪怕你用 std::nth_element 优化,也得先保证逻辑正确性——多数场景下,老老实实用 std::sort 更稳妥。
- 对
int arr[5] = {3,1,4,1,5}直接取arr[2]得到的是 4,但真实中位数是 3(排序后为{1,1,3,4,5}) -
std::vector比原生数组更易操作,推荐优先用它存数据 - 排序目标是升序;降序后取中间值会出错,别图省事跳过
std::less<int>()</int>或默认比较
奇偶长度要分开处理
中位数不是“总长度除以 2 下标”,而是:奇数长度取中间那个,偶数长度取中间两个的平均值。C++ 整数除法会截断,size/2 在偶数时刚好是靠右的中间索引,但左边那个是 size/2 - 1,漏掉就全错了。
- 长度为 5 → 索引 2(
5/2 == 2),没问题 - 长度为 4 → 索引应取 1 和 2(
4/2-1 == 1,4/2 == 2),不是只取 2 - 平均值类型要小心:
(arr[i] + arr[j]) / 2.0强制转double;写成/ 2会整除丢精度
用 std::vector + std::sort 最简可行
这是最不容易出错的组合,适合绝大多数实际需求。不要为了“避免复制”硬上原生指针+迭代器,除非你在嵌入式或性能敏感路径上真测出瓶颈。
#include <vector>
#include <algorithm>
#include <iostream><p>double median(std::vector<int> v) {
if (v.empty()) return 0.0;
std::sort(v.begin(), v.end());
size_t n = v.size();
if (n % 2 == 1) {
return v[n/2];
} else {
return (v[n/2 - 1] + v[n/2]) / 2.0;
}
}</int></p></iostream></algorithm></vector>
- 传值进函数是故意的——
std::sort要改内容,原数组/向量不该被意外修改 - 如果输入已是
const std::vector<int>&</int>,那就先std::vector<int> copy(v)</int>再排 - 别用
int返回中位数,哪怕输入全是整数——偶数长度时平均值可能是 .5 结果
想省排序开销?std::nth_element 只适用单次中位数
它能在 O(n) 平均时间找到第 k 小元素,但只保证“第 k 位正确”,左边无序、右边也无序。所以偶数长度时,你需要两个值(第 n/2-1 小和第 n/2 小),就得调两次或改用 std::partial_sort,反而更麻烦。
- 对奇数长度,
std::nth_element(v.begin(), v.begin()+n/2, v.end())后取v[n/2]可行 - 对偶数长度,不能只调一次——
std::nth_element不保证相邻位置关系,v[n/2-1]和v[n/2]不一定就是那两个中间值 - 实测中,小数组(std::sort 反而更快,现代 libc++/libstdc++ 对小范围做了优化
实际写业务代码时,中位数往往只是中间步骤,后面还要继续算标准差或做分桶。这时候排序一次、复用已排序结构,比反复调 nth_element 更清晰。别过早优化,先让逻辑跑通、边界 case 覆盖全。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











