Я изучаю общие двоичные деревья поиска (BST) и деревья AVL (AVL) в некоторых заметках, содержащих псевдокоды реализации. Я немного озадачен некоторыми деталями их реализации.
BST основан на struct Node
ниже
struct Node{
int key;
Node* parent;
Node* left;
Node* right;
//constructors
}
//methods
Версия AVL в основном такая же, но с несколькими полями для балансировки дерева (я назову ее AVLNode
для ясности, но в примечаниях такого различия нет):
struct AVLNode{
int key;
int height;
int size;
AVLNode* parent;
AVLNode* leftchild;
AVLNode* rightchild;
//constructors
}
//methods
Многие операции одинаковы между двумя деревьями, и я могу легко использовать шаблоны, чтобы повторно использовать их на обоих деревьях. Однако рассмотрим операцию insert
, которая вставляет новый узел. Код для 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
}
Теперь дело в том, что операция insert
дерева AVL в основном такая же. псевдокод, представленный в примечаниях, выглядит следующим образом:
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
, уже предоставленную для Node
. Использование шаблонной специализации означало бы просто написание другой специализации insert<AVLNode>
для AVLNode
, так что я не об этом.
Я думаю, что можно было бы определить AVLNode
как дочерний класс Node
, а затем использовать что-то вроде
struct AVLNode : Node {
//implementation
}
void avlInsert(int k, AVLNode* R){
Node *root=R;
insert(k,root);
AVLNode* N=find(x,R);
rebalance(N);
}
но я не совсем уверен, что это сработает, и я не знаю, как управлять указателями на parent
и потомков (т. е. они должны быть указателями на Node
внутри Node
и на AVLNode
внутри AVLNode
).
Есть ли способ избежать переписывания одного и того же кода?
Node*
вNode
, который должен бытьAVLNode*
вAVLNode
. Если я просто переопределю их вAVLNode
, дочерний класс будет иметь три бесполезных указателяNode*
вAVLNode
. - person luigi   schedule 09.09.2020insert
, который вы не хотите повторять? Я не понимаю, насколько много дублирования. Если код в основном такой же, вы можете использовать шаблоны. - person cigien   schedule 09.09.2020insert
. Повторение кода не имеет большого значения, простоAVLNode
может быть определено как дочернее дляNode
, и мне было интересно, можно ли использовать этот факт для повторного использования кода дляinsert
. Это также отвечает на @ThomasMatthews, я уже реализовал это с помощью шаблонов, мне просто интересно. - person luigi   schedule 09.09.2020