2015-05-22 138 views
0

我试图实现一个RedBlack树,该树包含一些2D点。我想要有2棵RedBlack树,第一棵根据它们的第一个元素(比如x)排序Points,第二个根据第二个元素(比如y)排序它们。我不想为这个任务分配两棵树。所以我决定将一个函数传递给一个比较点的红黑树的构造函数。例如:将函数赋值给另一个

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可以访问它。

回答

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

首先定义比较函数指针类型:

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); 
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; 
    } 
相关问题