我正在尝试维护一组完美的,堆有序的二叉树:
(对不起)。
所以,我认为创建一个 heapNode 类型,包含相关的子/父指针并持有一个元素,以及一个 heap 类型,它将实现这些操作在树上,会是直截了当的。至少,如果我只担心一棵树,我就会这样做。问题是,给定指向任何树中的节点的指针,我需要能够删除该节点。但是,只有指针,我无法弄清楚我将如何知道要调用的 heap 实例。
我的想法是,我没有这样的堆类型,只有节点,然后是某种类型的修饰符类型,它将实现所有树木作业。这个修饰符唯一能够知道的是如何操作 heapNodes (更改链接等)。我认为修饰符类型只是静态方法的集合,也许只是普通C函数的集合。
对这个问题有什么看法?我猜这是一个更普遍的问题:给定一个类的某个(数据)成员的引用,你如何轻松访问它上面的可用操作?我在C ++中这样做,我不太清楚。我很喜欢C。感谢。
答案 0 :(得分:0)
你从哪里获得指向树木的指针?恕我直言,这违反了你的树集合类的封装(如果没有,这可能是问题),并且是缺少抽象的标志。保持你的内部私密。
你知道你可以使用数组建模堆而不使用通过指针链接的节点吗?在C ++中,STL提供了执行此操作的功能。
template<typename T> class Forest {
public:
// functions to do something with the heap,
// but do not leak internals.
void do_something(T const& x) {
// pick a heap and add an element
mHeaps[0].push(x);
}
private:
// simple wrapper around STL heap functions
class Heap {
public:
void push(T const& x) {
mData.push_back(x);
std::push_heap(mData.begin(), mData.end());
}
T pop() {
std::pop_heap(mData.begin(), mData.end());
T const tmp(mData.back());
mData.pop_back();
}
private:
std::vector<T> mData;
};
std::vector<Heap> mHeaps;
};
如果需要迭代,请实现自定义迭代器迭代所有堆,但不要泄漏内部。客户不应该依赖于实施知识,例如堆积的实施方式。
如评论中所述,您正在使用堆实现优先级队列(cphstl.dk/Paper/TOCS-2011/journal.pdf)。我会建议这样的设计:
这些元素几乎可以单独实施和测试。优先级队列的客户端看不到任何实现。