C++ 实现二叉搜索树时对类的质疑
我正在研究一些包含实现伪代码的注释中的通用二进制搜索树(BST)和AVL树(AVL)。我对其实施的一些细节感到有点困惑 BST基于下面的C++ 实现二叉搜索树时对类的质疑,c++,class,templates,binary-search-tree,avl-tree,C++,Class,Templates,Binary Search Tree,Avl Tree,我正在研究一些包含实现伪代码的注释中的通用二进制搜索树(BST)和AVL树(AVL)。我对其实施的一些细节感到有点困惑 BST基于下面的struct节点 struct Node{ int key; Node* parent; Node* left; Node* right; //constructors } //methods AVL版本基本上是相同的,还有几个字段用于平衡树(为了清晰起见,我称之为AVLNode,但注释中没有这样的区别): 两棵树之间的许多操作是相同的
struct节点
struct Node{
int key;
Node* parent;
Node* left;
Node* right;
//constructors
}
//methods
AVL版本基本上是相同的,还有几个字段用于平衡树(为了清晰起见,我称之为AVLNode
,但注释中没有这样的区别):
两棵树之间的许多操作是相同的,我可以轻松地使用模板,以便在两棵树上重用它们。但是,请考虑操作<代码>插入< /代码>,它插入一个新节点。BST的代码类似于
//Insert node with key k in tree with root R
void insert(const int& k, Node* root){
Node* N=find(k, root); //finds where to insert the node
if (N->key>k)
N->leftchild=new Node(k,N); //inserts as a left child
else
N->rightchild=new Node(k,N); //inserts as a right child
}
struct AVLNode : Node {
//implementation
}
void avlInsert(int k, AVLNode* R){
Node *root=R;
insert(k,root);
AVLNode* N=find(x,R);
rebalance(N);
}
现在,关键是AVL树的insert
操作基本相同。注释中显示的伪代码如下所示:
void avlInsert(int k, AVLNode* R){
insert(k,R); //same operations as for Nodes, shown above
AVLNode* N=find(x,R); //find node inserted (generic operation for BST)
rebalance(N); //perform balancing operations specific to AVL trees
}
在这一点上我有点困惑,我知道上面只是一个伪代码,但我想知道是否有办法重用已经为节点提供的操作insert
。使用模板专门化只意味着为AVLNode
编写不同的专门化insert
,所以这不是我所指的
我认为一种方法是将AVLNode
定义为Node
的子类,然后使用
//Insert node with key k in tree with root R
void insert(const int& k, Node* root){
Node* N=find(k, root); //finds where to insert the node
if (N->key>k)
N->leftchild=new Node(k,N); //inserts as a left child
else
N->rightchild=new Node(k,N); //inserts as a right child
}
struct AVLNode : Node {
//implementation
}
void avlInsert(int k, AVLNode* R){
Node *root=R;
insert(k,root);
AVLNode* N=find(x,R);
rebalance(N);
}
但我不太确定这是否可行,我不知道如何管理指向父节点
和子节点的指针(即,它们必须是指向节点
内部节点
和AVLNode
内部AVLNode
的指针)
有没有办法避免重写相同的代码?您可以在这里使用CRTP。这将允许您在基类中创建左、右和父节点。例如,考虑这样的事情:
模板
结构BaseNode{
int键;
T*父母;
T*左;
T*对;
};
struct AVLNode:生成代码的公共BaseNode
作为旁白请不要使用原始指针以及新建和删除。你会得到很多内存泄漏,尤其是当一个指针因为其父指针被删除而“丢失”时。考虑使用智能指针,如“代码> UNQuyYPPTR <代码>或<代码> SydDypPTR 您考虑过OOP吗?看起来AVL节点是一个特殊的节点。您可以让AVL node扩展None,然后尽可能使用generic node。请阅读最后一段。要点是在
节点
中有3个指针节点*
,它们必须是AVLNode*
中的AVLNode*
。如果我只是在AVLNode
中重新定义它们,子类将在AVLNode
中有三个无用的节点*
指针。您可以显示不希望重复的插入
代码吗?我不清楚有多少重复。如果代码基本相同,您可能可以使用模板。不要为继承或简化而烦恼。你将付出比你所获得的利益更多的努力。由于结构是独立的,所以请保持这种方式。