C++ 我应该如何在c++;?
我有两棵AVL树,每棵树都通过不同的参数对相同的数据进行排序(比如,其中一棵树实际上存储了数据,另一棵树只是指向数据)。在本例中,左边的树按左边的数字排序,右边的树按右边的数字排序:C++ 我应该如何在c++;?,c++,pointers,tree,encapsulation,C++,Pointers,Tree,Encapsulation,我有两棵AVL树,每棵树都通过不同的参数对相同的数据进行排序(比如,其中一棵树实际上存储了数据,另一棵树只是指向数据)。在本例中,左边的树按左边的数字排序,右边的树按右边的数字排序: 58 64 / \ / \ 22 73 22 58 / \ / \ / \ / \ 19
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)
time中的左树中找到节点,如果我在要删除的节点上,我可以从另一棵log(n)
每棵树的每棵树中删除它
但是,我需要从左侧树中的节点到右侧节点的链接:
58 ------>64
/ \ | / \
22 73 | 22 58
/ \ / \ | / \ / \
19 36 64 81 | 81 73 36 19
|______|
否则,我需要在n
time中找到右树中的节点,因为它不是按左数字排序的
我的树
类不允许直接访问节点,只允许访问数据(我希望保持这种方式)
我是否别无选择,只能将我的数据结构实现为
树的朋友类?这样行吗?或者有什么优雅的方法可以做这样的事情吗?如果有人遇到这个问题,我打算这么做
如果我得到任何关于为什么这是一个坏主意的有说服力的评论,我将删除答案/编辑它
基本上,我将创建一个Forrest
类,它本质上是一个带有数据本身的列表
,以及一个专门的AVL树(sappling
s)的内部列表,我将使Forrest
成为上述sappling
s的朋友
_______________ ... _______
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
类,以便同一树
类型的不同实例可以进行不同的排序,并允许Forrest
定义树苗
对数据指针进行排序的方法
基本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());
};
这是我将使用的列表
类:
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.
};
呼
希望这能起作用。我只是想澄清一下。。。这里涉及的其他数据类型是什么?理想情况下,您可以将指针放在树中的那些数字对上,而不是数字本身。您可以使用第一个数字作为排序标准创建第一棵树,使用第二个数字创建第二棵树。但是,由于“Tree
类不允许直接访问节点,而只允许访问数据”,因此您必须提出一些额外的数据结构来将树节点映射到树节点,例如std::unordered_map
。
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.
};
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; }
};
};