我试图实现RedBlack树,这棵树包含一些2D点。我想要2个RedBlack树,第一个根据它们的第一个元素(比如x)对Points进行排序,第二个根据第二个元素(比如y)对它们进行排序。我不想为此任务分别拥有2棵树。所以我决定将一个函数传递给比较这些点的红黑树的构造函数。例如:
bool xCompare(Point a, Point b) {return a.x < b.x ;}
bool yCompare(Point a, Point b) {return a.y < b.y ;}
所以我可以写:
RedBlackTree A(xCompare); RedBlackTree B(yCompare);
问题是我不知道如何将这个传递的函数保存到构造函数中,这样每次调用insert
函数时,插入都基于这个传递的函数。例如,如果我写:
A.insert(make_point(2,3));
A.insert(make_point(7,5));
A.insert(make_point(11,1));
A
中的点数应根据xCompare
进行排序。但我不知道如何在我的班级中保存这个xCompare
函数(如私有函数),以便insert
可以访问它。
答案 0 :(得分:2)
您可以为树提供一个函数指针数据成员,并在构造函数中设置它:
struct rb_tree
{
rb_tree(bool(*)(Point a, Point b) cmp) : cmp_(cmp) { .... }
....
private:
bool (*cmp_)(Point a, Point b);
};
然后,
rb_tree A(xCompare);
rb_tree(B(yCompare);
通过使用仿函数的模板参数或将数据成员设为std::function<bool(Point, Point)>
,可以将其推广到任何类型的兼容可调用对象。例如
struct rb_tree
{
rb_tree(std::function<bool(Point, Point)> cmp) : cmp_(cmp) { .... }
....
private:
std::function<bool(Point, Point)> cmp_;
};
与函数指针示例的用法类似,或
template <typename F>
struct rb_tree
{
rb_tree(F cmp) : cmp_(cmp) { .... }
....
private:
F cmp_;
};
然后
struct cmpA{ bool operator()(Point a, Point b); };
struct cmpB{ bool operator()(Point a, Point b); };
rb_tree<cmpA> A(cmpA_instance);
rb_tree<cmpB> A(cmpB_instance);
但请注意,在最后一个示例中,树的类型不同。
答案 1 :(得分:1)
首先定义比较函数指针类型:
typedef bool (*TreeCompare)(Point a, Point b);
然后在你的课程中添加一个成员并在构造函数中设置它的值:
class RedBlackTree {
private:
TreeCompare m_CompareFunction;
public:
RedBlackTree(TreeCompare compareFunction) {
m_CompareFunction = compareFunction;
}
void Insert(Point a, Point b) {
if(m_CompareFunction(a, b))
// Do Something
}
}
最后,创建一个实例:
RedBlackTree myTree(xCompare);
答案 2 :(得分:1)
我为此实现了一个函数指针方法。而且还计划很快用一个纯粹的面向对象更新答案。
typedef struct _Point
{
int x;
int y;
} Point;
typedef (bool)(*COMPARE)(Point& a, Point& b);
bool xCompare(Point a, Point b) {return a.x < b.x ;}
bool yCompare(Point a, Point b) {return a.y < b.y ;}
Point make_point(int x, int y)
{
Point pt = {x, y};
retun pt;
}
class RedBlackTree
{
private:
COMPARE _fnCompare;
public:
RedBlackTree(COMPARE compare)
{
_fnCompare = compare;
};
void Insert(Point ptNew)
{
bool bResult = _fnCompare(ptNew);
if(bResult)
{
//Do Something
}
else
{
//Do something else;
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
RedBlackTree a(xCompare);
A.insert(make_point(2,3));
A.insert(make_point(7,5));
A.insert(make_point(11,1));
return 0;
}
现在使用OOPS概念。
typedef struct _Point
{
int x;
int y;
}
Point make_point(int x, int y)
{
Point pt = {x, y};
retun pt;
}
class IComparer
{
public:
virtual bool Compare(Point& a, Point& b) = 0;
};
class AComparer: public IComparer
{
public:
virtual bool Compare(Point& a, Point& b)
{
return a.x < b.x ;
};
};
class BComparer: public IComparer
{
public:
virtual bool Compare(Point& a, Point& b)
{
return a.y < b.y;
};
}
class RedBlackTree
{
private:
IComparer * m_pComparer;
public:
RedBlackTree(IComparer * comparer)
{
m_pComparer = comparer;
};
void Insert(Point ptNew)
{
bool bResult = m_pComparer->Compare(ptNew, otherPoint);
if(bResult)
{
//Do Something
}
else
{
//Do something else;
}
}
~RedBlackTree()
{
delete m_pComparer;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
RedBlackTree a(new AComparer());
A.insert(make_point(2,3));
A.insert(make_point(7,5));
A.insert(make_point(11,1));
return 0;
}