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

重载Node类<运算符无效:set<Node*>无法按自定义规则排序求助

解决set<Node*>自定义排序失效问题

问题根源

你重载的Node::operator<是用于Node对象之间的比较,但std::set<Node*>默认使用std::less<Node*>作为比较器,它直接比较的是指针的内存地址,而非指针指向的Node对象内容。所以不管怎么重载Node类的<运算符,都不会被set调用,最终排序结果是按指针地址随机排列。

解决方案:给set指定自定义比较器

需要为set提供一个能比较两个Node指针指向对象的比较规则,具体有两种常用方式:

方式1:使用结构体作为比较器

定义一个重载了operator()的结构体,专门用于比较Node指针:

#include <iostream>
#include <set>
using namespace std;

class Node {
public:
    int x, y;
    Node *prev, *next;

    Node(int x, int y) {
        this->x = x; this->y = y;
        this->prev = this->next = nullptr;
    }
};

// 自定义比较器:按Node的x值升序排序
struct CompareNode {
    bool operator()(const Node* a, const Node* b) const {
        // 若存在插入nullptr的场景,需额外处理,比如:
        // if (!a) return !b;
        // if (!b) return false;
        return a->x < b->x;
    }
};

int main() {
    // 声明set时指定自定义比较器
    set<Node*, CompareNode> S;

    S.insert(new Node(2, 4));
    S.insert(new Node(3, 2));
    S.insert(new Node(1, 4));
    S.insert(new Node(5, 1));
    S.insert(new Node(4, 3));

    for (auto itr : S)
        cout << itr->x << endl;

    // 释放内存,避免内存泄漏
    for (auto node : S)
        delete node;

    return 0;
}

方式2:使用lambda表达式(C++11及以上)

如果不想定义单独的结构体,也可以用lambda作为比较器,但需要借助decltype来推导类型:

int main() {
    auto compare = [](const Node* a, const Node* b) {
        return a->x < b->x;
    };
    set<Node*, decltype(compare)> S(compare);

    // 后续插入和遍历逻辑同上
}

注意事项

  • 确保传入set的指针都是有效指针,避免空指针解引用。如果需要支持nullptr,要在比较器中添加判断逻辑。
  • 原来的Node::operator<仅在直接比较Node对象(如Node a(1,2); Node b(3,4); if(a < b))时生效,和set存储指针的场景无关。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 11:40:50