您的实施要求bool operator()(Edge*, Edge*)
作为常规member班级的Edge
这是可能的,但很少这样做。
标准库算法的比较器有以下惯用风格:all其中必须提供正在处理的序列中所包含对象的严格弱排序:
- 独立函子类
- 独立式
operator <
超载
- 对象类成员
operator <
超载。
- 独立功能
- 静态类函数
- 静态类仿函数类
- 其他几个...
此列表中的第五 (5) 个内容与他们的指示最接近trying要做,但它是never实施为operator()
. It is possible作为以下成员做 (1)Edge
,但要做到这一点Edge
类型必须支持默认构造。稍后我将解释如何做到这一点。在上面列出的选项中,对于此特定情况,性能(内联的可能性)和实现简便性的最佳候选者是(1)和(6)。如果您的队列实际持有Edge
objects而不是Edge
pointers(3) 将是一个自然的选择并且提供不错的性能。
有序容器和容器适配器(如优先级队列)的比较器的要点是比较其中保存的两个项目是否符合严格弱序。如果你不知道那是什么,看到这个链接。在实施中,归结为:如果,并且仅当 x < y
return true,否则返回false。这意味着必须执行以下规定:
-
x < x
总是返回false
- if
x < y
回报true, then y < x
must return false
- if both
x < y
and y < x
返回 false,则x
is 相等的 to y
不小心将比较器编码为不遵守这些规则是一个常见的错误。谨防这一点。
无论如何,我离题了。这样做的一种方法正确地给定您的类定义并使用上面列表中的 (1) 是:
阶级边缘
class Edge
{
public:
Edge(Vertex* src, Vertex* dst, double w)
: source(src), destination(dst), weight(w)
{
};
// note: const-ness
double getWeight() const { return weight; }
Vertex const* getSource() const { return source; }
Vertex* getSource() { return source; }
Vertex const* getDestination() const { return destination; }
Vertex* getDestination() { return destination; }
private:
Vertex* source;
Vertex* destination;
double weight;
};
类 CmpEdgePtrs
struct CmpEdgePtrs
{
bool operator()(const Edge* lhs, const Edge* rhs) const
{
return lhs->getWeight() < rhs->getWeight();
}
};
类图
class Graph
{
// rest of class stuff
private:
priority_queue<Edge*, vector<Edge*>, CmpEdgePtrs> edges;
};
老实说,这是对共享智能指针的使用的尖叫,但我把它留给你了。上面的代码很有可能在实现优先级队列逻辑的标准库算法中的整个使用位置内联比较器,因此考虑到指针容器的约束,这样的性能将很有可能达到最佳。
完成分配的要求
This can完全在课堂上完成Edge
,因为它毕竟只是一个类类型。作为优先级队列适配器的模板参数传递的第三种类型公开了bool operator()
,没有什么可以阻止你只是做一个例子Edge
为你做那件事。这很奇怪,但它仍然可以通过一些修改来工作:
首先,移动bool operator()(const Edge*, const Edge*) const
to the Edge
类,声明为 public。其次,提供一个默认构造函数Edge
,因为在创建仿函数来执行比较时,优先级队列的内部算法将需要它。
class Edge
{
public:
// regular parameterized construction
Edge(Vertex* src, Vertex* dst, double w)
: source(src), destination(dst), weight(w)
{
};
// ADDED: allows parameterless initialization
Edge()
: source(), designation(), weight()
{}
// note: const-ness
double getWeight() const { return weight; }
Vertex const* getSource() const { return source; }
Vertex* getSource() { return source; }
Vertex const* getDestination() const { return destination; }
Vertex* getDestination() { return destination; }
// ADDED: used when an instance of `Edge` is used as comparator functor
bool operator ()(const Edge* lhs, const Edge* rhs) const
{
return lhs->weight < rhs->weight;
}
private:
Vertex* source;
Vertex* destination;
double weight;
};
class Graph
{
// rest of class stuff
private:
// NOTE: uses Edge-type as the functor type that will
// deliver the comparison of Edge pointers.
priority_queue<Edge*, vector<Edge*>, Edge> edges;
};
This is 极不寻常,但好处是允许函子直接访问成员变量Edge
对象被比较,而不是通过公共 getter 和 setter 或必须与比较器成为好友。但它有一个缺点。没有什么可以阻止某人besides构建容器适配器Edge
不指定来源、目的地和重量的对象。
简而言之,这样做没有什么好处,并且不正确使用使这项工作所需的代码可能会出现问题,为此,我会推荐第一个选项。
祝你好运