You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为已实现的归并排序模板函数添加自定义比较器

给模板化归并排序添加自定义比较器的实现方案

嘿,你已经搞定了模板化的归并排序,距离支持自定义排序逻辑只差最后几步啦!下面我会一步步带你实现这个功能,代码示例和注意事项都给你安排得明明白白:

1. 给模板函数添加比较器参数

首先,我们需要给归并排序的模板增加一个可选的比较器模板参数,默认使用std::less<T>(也就是升序排序的逻辑)。这样用户既可以用默认行为,也能传入自己的比较器。

同时,在函数参数里也要加上这个比较器的实例(同样给默认值,方便调用)。如果你的归并排序拆分成了merge和mergeSort两个函数,那两个函数都需要加上这个参数哦。

2. 替换排序逻辑中的比较判断

原来你代码里直接用left[i] < right[j]这种硬编码的比较,现在要全部替换成用传入的比较器对象来判断。比如把if (a < b)改成if (comp(a, b)),这样就完全交给自定义比较器来决定元素的顺序了。

3. 完整代码示例

下面是改造后的完整模板化归并排序代码,包含了简化的对外调用接口:

#include <vector>
#include <functional> // 必须包含这个头文件才能用std::less、std::greater

// 归并操作的模板函数,带比较器参数
template <typename T, typename Comparator = std::less<T>>
void merge(std::vector<T>& arr, int left, int mid, int right, Comparator comp) {
    int n1 = mid - left + 1;
    int n2 = right - mid;

    std::vector<T> leftArr(n1);
    std::vector<T> rightArr(n2);

    // 复制子数组元素
    for (int i = 0; i < n1; ++i)
        leftArr[i] = arr[left + i];
    for (int j = 0; j < n2; ++j)
        rightArr[j] = arr[mid + 1 + j];

    int i = 0, j = 0, k = left;
    // 用自定义比较器替代原有的<判断
    while (i < n1 && j < n2) {
        if (comp(leftArr[i], rightArr[j])) {
            arr[k] = leftArr[i];
            ++i;
        } else {
            arr[k] = rightArr[j];
            ++j;
        }
        ++k;
    }

    // 复制剩余元素
    while (i < n1) {
        arr[k] = leftArr[i];
        ++i;
        ++k;
    }
    while (j < n2) {
        arr[k] = rightArr[j];
        ++j;
        ++k;
    }
}

// 递归的归并排序核心函数,带比较器参数
template <typename T, typename Comparator = std::less<T>>
void mergeSortCore(std::vector<T>& arr, int left, int right, Comparator comp) {
    if (left < right) {
        int mid = left + (right - left) / 2; // 避免溢出的写法

        mergeSortCore(arr, left, mid, comp);
        mergeSortCore(arr, mid + 1, right, comp);

        merge(arr, left, mid, right, comp);
    }
}

// 对外简化的调用接口,无需传入左右边界
template <typename T, typename Comparator = std::less<T>>
void mergeSort(std::vector<T>& arr, Comparator comp = Comparator()) {
    if (!arr.empty()) {
        mergeSortCore(arr, 0, arr.size() - 1, comp);
    }
}

4. 使用示例

现在你可以轻松实现各种排序需求了:

默认升序排序

std::vector<int> nums = {3, 1, 4, 1, 5, 9};
mergeSort(nums); // 默认使用std::less<int>,输出升序数组

降序排序(用标准比较器std::greater)

mergeSort(nums, std::greater<int>()); // 输出降序数组

自定义比较器(比如按字符串长度排序)

std::vector<std::string> strs = {"apple", "banana", "cherry", "date"};
// 用lambda表达式做自定义比较器:按字符串长度从小到大排
auto compareByLength = [](const std::string& a, const std::string& b) {
    return a.size() < b.size();
};
mergeSort(strs, compareByLength);
// 排序后结果:date, apple, banana, cherry

5. 关键注意事项

  • 头文件依赖:一定要包含<functional>头文件,不然std::less和std::greater这些标准比较器会报错。
  • 严格弱序要求:自定义比较器必须满足严格弱序规则,否则排序结果会出现未定义行为。简单来说:
    • comp(a, a)必须返回false
    • 如果comp(a, b)为true,那么comp(b, a)必须为false
    • 如果comp(a, b)和comp(b, c)都为true,那么comp(a, c)也必须为true
  • 递归传递比较器:别忘了在递归调用归并排序的时候把比较器传下去,不然递归内部会用默认的比较器,导致逻辑不一致。

内容的提问来源于stack exchange,提问作者Bluefarmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:34:56