2015-04-26 3 views
0

Ниже приведен код, который я написал для вставки узла в Дерево простого двоичного поиска. Теперь я пытаюсь реализовать Red Black Tree, наследуя тот же класс Node в класс RBNode.Использование Inheritence эффективно в C++

void Node::insert_node(Tree *t) 
{ 
    Node *cur_node = t->get_root(); 
    Node *prev_node; 
    while(NULL != cur_node) 
    { 
     prev_node = cur_node; 
     if(this->data < cur_node->data) 
     { 
      cur_node = cur_node->left; 
     } 
     else 
     { 
      cur_node = cur_node->right; 
     } 
    } 


    if(NULL == t->get_root()) 
    { 
     cur_node = this; 
     t->set_root(cur_node); 
    } 
    else 
    { 
     if(this->data < prev_node->data) 
     { 
      prev_node->left = this; 
     } 
     else 
     { 
      prev_node->right = this; 
     } 
     this->parent = prev_node; 
    } 
} 

Эта функция будет оставаться одинаковой для RBNode, за исключением того, что узел * следует заменить RBNode * и дерево * заменяется RBTree *. Я думаю, что бесполезно писать ту же функцию в классе RBNode, которая по сути делает то же самое. Если я использую одну и ту же функцию, я не могу получить доступ к членам RBNode, так как то, что я вставил в Дерево, является узлом.

Каков эффективный способ достижения этого. Я новичок в C++, поэтому, если я пропустил что-то очевидное, сообщите мне.

+0

Если вы нацелены на максимальную эффективность, структура данных, подобная этой, включает в себя много рывков, которые могут привести к большому количеству промахов в кэше. Более смежная структура данных, такая как дерево B +, вероятно, будет быстрее. Кроме того, в зависимости от ваших фактических типичных данных вам может даже не понадобиться дерево. –

ответ

2

Вам не нужно использовать наследование на всех, но вы можете. Решение без наследования было бы использовать шаблоны. В следующем порядке:

template <class N, class T> 
void insert_node(N *node, T *tree); 

Этот код будет работать для обоих видов узлов. Проблема заключается в том, что он должен быть расположен либо глобально, либо в третьем неродственном классе. Вы можете наследовать Node от абстрактного класса INode и Tree наследовать от абстрактного класса ITree. Эта функция будет расположена в INode. Полученные узлы и деревья будут иметь любую функциональность, уникальную для них.

+0

Этот подход выглядит хорошо. Я попробую. Благодарю. –

2

Если RBNode наследует от Node и RBTree наследует от Tree, то RBNode являетсяNode и RBTree является Tree. Фактически, если эта функция равна public или protected, а сами наследование public или protected, вы сможете позвонить по телефону RBNode, и это сработает.

Вот небольшой пример:

class Base { 
    public: 
    int foo() {return 2;} 
}; 

class Derived : public Base { 
    //nothing 
}; 

int main() { 
    Derived d; 
    cout<<d.foo()<<endl; //prints 2 
} 
+0

Да. Но я не могу получить доступ к членам RBNode, если я использую одну и ту же функцию. –

+0

Нет, вы не сможете получить доступ к каким-либо конкретным членам RBNode. Тем не менее, вы сможете получить доступ к любым членам, которые также являются членами узла. Если ваша цель - иметь другое поведение в этой функции, то вы либо должны использовать другую функцию (поскольку вы хотите другое поведение), либо, лучше, использовать виртуальную функцию в узле, которую RBNode переопределяет. Вы также можете посмотреть в dynamic_cast, но это не всегда лучший вариант. – IanPudney

+0

Большое спасибо за входные данные. Я использовал шаблоны, чтобы исправить проблему. –

Смежные вопросы