2015-05-22 134 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; 
    } 
相關問題