2015-11-19 5 views
3

Я работал над реализацией основного двоичного дерева поиска.Перегрузка рекурсивной функции C++

И я определил рекурсивную функцию для печати дерева в порядке

void printTree(Node *n){ 
    if (n){ 
     printTree (n -> left); 
     n -> printNode(); 
     printTree (n -> right); 
    } 
} 

При вызове этой функции я вообще почти всегда буду называть его с начальным значением узел * п является указателем корневой узел.

это нормально, чтобы перегрузить функцию, подобную этой.

void printTree() {printTree(root);}; 

это принятый способ борьбы с рекурсивной функцией, в которой аргумент для первого вызова всегда будет тем же /, используя один и тот же указатель/переменным и т.д.

Есть еще один способ таких ситуаций, например, почти все рекурсивные функции, которые будут выполняться для двоичного дерева поиска, попадут в один и тот же случай. то есть аргумент для первого вызова всегда является корневым узлом.

+3

Вы всегда будете иметь _one_ tree в вашей программе? – Petr

+0

Для этого случая да – Koborl

+0

@Koborl Пожалуйста, не забудьте принять ответ, который вам больше нравится –

ответ

3

Это нормально перегрузить его, если root является членом класса и инициализируется в конструкторе класса.

class Tree 
{ 
    public: 
    Tree() : m_root(new Node()) { } 
    void printTree(Node *n); 
    void printTree() { printTree(m_root); } 

    private: 
    Node* m_root; 
}; 
2

версии, которую представила имеет один большой недостаток: вызов printTree() всегда будет печатать один конкретного дерева. Это делает ваш код практически невозможным для повторного использования; что вы будете делать, если вам нужно два деревьев в вашей программе?

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

Однако более реалистичная ситуация может заключаться в том, что у вас есть отдельный class Tree, который отличается от класса Node. В этом случае у вас может быть Tree::print(Node*) для печати поддерева и перегруженного Tree::print() для печати всего дерева. В этом случае типичное использование будет по линии tree.print();, а здесь tree переменная уже определяет, какое дерево печатать, а перегрузка имеет смысл и удобна в использовании.

2

Использование бутстрапов для подобных методов для определенных структур данных на 100% отлично, возможно, даже более эффективно.

Если это так, то настроить класс таким образом, так, чтобы главный printTree метода является частным и бутстраповским является публичным методом, который вызывается так:

class Tree 
{ 
    private: 
     Node *root; 
     void printTree(Node *n); 

    public: 
     ... 
     ... 
     void printTree(); 
}; 

void Tree::printTree() 
{ 
    printTree(root); 
} 
+0

'root' член должен быть инициализирован в Tree constructor –

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