将功能分配给另一个

时间:2015-05-22 05:50:55

标签: c++ red-black-tree

我试图实现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可以访问它。

3 个答案:

答案 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;
   }