【问题标题】:How should I implement communication between instances in c++?我应该如何在 C++ 中实现实例之间的通信?
【发布时间】:2014-11-19 19:49:21
【问题描述】:

我有两棵 AVL 树,每棵树都按不同的参数对相同的数据进行排序(例如,其中一棵树实际上存储数据,另一棵树只是指向它)。在示例中,左边的树按左边的数字排序,右边的树按右边的数字排序:

               58             64   
              /   \          /   \
            22     73      22     58
           /  \   /  \    /  \   /  \
          19  36 64  81  81  73 36  19

假设我想删除一个项目(从两棵树中,因为它是相同的数据),但我只得到了左边的数字。例如,在调用removeLeft(6) 之后,我的树将如下所示:

               58             36   
              /   \          /   \
            22     73      22     58
           /  \      \    /  \      \
          19  36     81  81  73     19

我可以在 log(n) 时间找到左侧树中的节点,如果我在想要删除的节点处,我可以将它从每棵树的另一棵树中的另一棵树中删除它log(n)

但是,我需要从左侧树中的节点到右侧节点的链接:

               58         ------>64   
              /   \      |      /   \
            22     73    |    22     58
           /  \   /  \   |   /  \   /  \
          19  36 64  81  |  81  73 36  19
                  |______|

否则我需要在n 时间找到右侧树中的节点,因为它不是按左侧数字排序的。

我的Tree 类不允许直接访问节点,只能访问数据(我希望保持这种状态)。

我是否别无选择,只能将我的数据结构实现为Tree 类的friend 类?那还能用吗?还是有一些优雅的方式来做这样的事情?

【问题讨论】:

  • 只是为了澄清......这里涉及的其他数据类型是什么?
  • 理想情况下,您会将指向这些数字对的指针放在树中,而不是数字本身。您将使用第一个数字作为排序标准制作第一棵树,使用第二个数字制作第二棵树。但是,由于您的“Tree 类不允许直接访问节点,只能访问数据”,因此您将不得不提出一些额外的数据结构来将树节点映射到树节点,例如 std::unordered_map

标签: c++ pointers tree encapsulation


【解决方案1】:

如果有人遇到这个问题,我打算这样做......

如果我得到任何有说服力的 cmets 说明为什么这是一个坏主意,我将删除答案/对其进行编辑。

基本上,我将创建一个 Forrest 类,它本质上是一个带有数据本身的 List,以及一个专用 AVL 树的内部列表 (Saplings),然后我将创建Forrest 一个friend 表示Saplings。

       _______________ ... _______
Data: |19     |22     |...|81     |
      |PTR->M7|PTR->M2|...|PTR->M1|
      |PTR->N1|PTR->N2|...|PTR->N7|
           _____
Saplings: |T1|T2|

T1:
                       N4:PTR->58
                     /            \
            N2:PTR->22             N6:PTR->73 
            /        \               /      \
      N1:PTR->19   N3:PTR->36  N5:PTR->64  N7:PTR->81

T2:
                       M4:PTR->64
                     /            \
            M2:PTR->22             M6:PTR->58 
            /        \               /      \
      M1:PTR->81   M3:PTR->73  M5:PTR->36  M7:PTR->19

另外,我将创建一个Compare 类,以便相同Tree 类型的不同实例可以进行不同的排序,并允许Forrest 定义Sapling 对指向数据的指针进行排序的方法。

基本的 AVL 树:

// Base AVL type, incomplete but for the purpose of this question it'll do
template<typename T>
class AVL {
public:
    // Compare type, so different trees can sort differently
    class Compare {
    public:
        virtual bool less(const& T, const& T) = 0;
        virtual bool equal(const& T, const& T) = 0;
    };
protected:
    // Default compare type, to utilize type T's default comparison operators
    class DefaultCompare : public AVL<T>::Compare {
    public:
        bool less(const& T a, const& T b) { return a<b; }
        bool equal(const& T a, const& T b) { return a==b; }
    };
    // AVL tree node. Will be extended in the Sapling
    class Node {
    public:
        Node *_parent, *_left, *_right;
        T _data;
    };
public:
    AVL(const& AVL<T>::Compare = DefaultCompare());
};

扩展它,用于Forrest

template<typename T>
class Sapling: public AVL<T> {
public:
    friend class Forrest;
};

这是我将使用的 List 类:

template<typename T>
class List {
protected:
    // A list node: prev, next and data
    class Node {
    public:
        Node *_next, *_prev;
        T _data;
    };
    // The list itself
    Node* _head;
public:
    ... // Setters, getters, iterator... etc.
};

定义Forrest 类(事实上,Forrest 是一个列表):

template<typename T>
class Forrest: public List<T> {
private:
    // Extend the list node to include all the Sapling nodes pointing to this data
    class Node: public List<T>::Node {
        List<AVL::Node*> _sapling_nodes;
    };
    // The Saplings themselves store pointers to list nodes, so the data itself
    // is stored in the main list (the _head field, inherited from List<T>)
    List<AVL<Forrest::Node*> > _saplings;
    // Create a Compare object so pointers to the data can be compared in the saplings:
    class ComparePtrs: public AVL<Forrest::Node*>::Compare {
    public:
        bool less(const& Node* a, const& Node* b) { return a->_data < b->_data; }
        bool equal(const& Node*, const& Node*) { return a->_data == b->_data; }
    };
};

呼……

希望这行得通。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    相关资源
    最近更新 更多