2015-02-13 2 views
0

все! Я пытаюсь внедрить двоичное дерево поиска простого шаблона. Я столкнулся с проблемой пары с определениями функций. Ниже мой BST код классаКак правильно использовать вложенный класс класса шаблона?

#ifndef BINARY_SEARCH_TREE_H 
#define BINARY_SEARCH_TREE_H 

#include <iostream> 
#include <stdlib.h> 

using namespace std; 

template<class T> 
class BST 
{ 
    struct TreeNode { 
     TreeNode* left; 
     TreeNode* right; 
     T value; 
    }; 

    //member functions 
    void destroyTree(TreeNode* leaf); 
    void insert(T key, TreeNode* leaf); 
    TreeNode* search(T key, TreeNode* leaf); 
    void printInOrder(TreeNode* leaf); 
    void printPreOrder(TreeNode* leaf); 
    void printPostOrder(TreeNode* leaf); 

    //memebr variables 
    TreeNode* root; 
public: 

    enum Traversal { INORDER, PREORDER, POSTORDER }; 

    BST(); 
    BST(T key); 
    ~BST(); 

    void insert(T key); 
    TreeNode* search(T key); 
    void printTree(T option); 
    void destroyTree(); 
}; 

template <class T> 
BST<T>::BST() 
{ 
    root = NULL; 
}; 

template <class T> 
BST<T>::BST(T key) 
{ 
    root = new TreeNode; 
    root->left = NULL; 
    root->right = NULL; 
    root->value = key; 
}; 

template <class T> 
BST<T>::~BST() 
{ 
    destroyTree(); 
}; 

template <class T> 
void BST<T>::destroyTree(TreeNode* leaf) 
{ 
    if (leaf->left != NULL) destroyTree(leaf->left); 
    if (leaf->right != NULL) destroyTree(leaf->right); 
    delete leaf; 
    leaf = nullptr; 
}; 

template <class T> 
void insert(T key, BST<T>::TreeNode* leaf) 
{ 
    if (leaf->value == key) 
    { 
     cout << "failed inserting node: duplicate item" << endl; 
     return; 
    } 
    else if (leaf->value < key) 
    { 
     if (leaf->right != NULL) insert(key, leaf->right); 
     else 
     { 
      TreeNode newNode = new TreeNode; 
      newNode->left = NULL; 
      newNode->right = NULL; 
      newNode->value = key; 
      leaf->right = newNode; 
     } 
    } 
    else 
    { 
     if (leaf->left != NULL) insert(key, leaf->left); 
     else 
     { 
      TreeNode newNode = new TreeNode; 
      newNode->left = NULL; 
      newNode->right = NULL; 
      newNode->value = key; 
      leaf->left = newNode; 
     } 
    } 
}; 

template <class T> 
BST<T>::TreeNode* BST<T>::search(T key, TreeNode* leaf) 
{ 
    if (leaf == NULL) return NULL; 
    if (leaf->value == key) return leaf; 
    else if (leaf->vluae < key) return search(key, leaf->right); 
    else return search(key, leaf->left); 
}; 

template <class T> 
void printInOrder(TreeNode* leaf) 
{ 
    if (leaf->left != NULL) printInOrder(leaf->left); 
    cout << leaf->value << " "; 
    if (leaf->right != NULL) printInOrder(leaf->right); 
}; 

template <class T> 
void printPreOrder(TreeNode* leaf) 
{ 
    cout << leaf->value << " "; 
    if (leaf->left != NULL) printPreOrder(leaf->left); 
    if (leaf->right != NULL) printPreOrder(leaf->right); 
}; 

template <class T> 
void printPostOrder(TreeNode* leaf) 
{ 
    if (leaf->left != NULL) printPostOrder(leaf->left); 
    if (leaf->right != NULL) printPostOrder(leaf->right); 
    cout << leaf->value << " "; 
}; 

template <class T> 
void BST<T>::insert(int key) 
{ 
    if (this->root == NULL) 
    { 
     this->root = new TreeNode; 
     this->root->left = NULL; 
     this->root->right = NULL; 
     this->root->value = key; 
    } 
    else insert(key, root); 
}; 

template <class T> 
BST<T>::TreeNode* BST<T>::search(int key) 
{ 
    search(key, this->root); 
}; 

template <class T> 
void BST<T>::printTree(int option) 
{ 
    switch (option) 
    { 
    case BST<T>::INORDER: 
     printInOrder(this->root); 
     cout << endl; 
     break; 
    case BST<T>::POSTORDER: 
     printPostOrder(this->root); 
     cout << endl; 
     break; 
    case BST<T>::PREORDER: 
     printPreOrder(this->root); 
     cout << endl; 
     break; 
    } 
}; 

template <class T> 
void BST<T>::destroyTree() 
{ 
    destroyTree(this->root); 
}; 

#endif 

Как вы можете видеть, для void insert(T key, BST<T>::TreeNode* leaf) и BST<T>::TreeNode* BST<T>::search(T key, TreeNode* leaf) функции мне нужно сделать что-то с TreeNode класса как возвращающий объект его или передать его в функцию, которая является вложенный тип, определенный в классе BST. Ошибки, которые я получаю, связаны с синтаксическими ошибками, но я не знаю, где я ошибаюсь в коде. Любые советы или предложения будут оценены!

+1

Куча отсутствует 'BST ::' ы, чтобы начать с. Для функций 'search' также требуется' typename' спереди. –

+0

«Ошибки, которые я получаю, связаны с ошибками синтаксиса, но я не знаю, где я ошибаюсь в коде». Ошибки, безусловно, содержат эту информацию. Но для того, чтобы мы могли использовать эту информацию, вам нужно разместить ошибки. – Angew

+0

Синтаксическая ошибка для функции вставки - это синтаксическая ошибка: идентификатор «TreeNode». – user3377437

ответ

2

Вы должны:

  • заменить каждый TreeNode на BST<T>::TreeNode, потому что могут быть разные TreeNode определения так что компилятор должен знать тот, о котором вы говорите.

  • добавить typename перед каждым BST<T>::TreeNode. Может существовать несколько разных определений для BST<T>::TreeNode, даже некоторых, которые не являются типами, поэтому вам нужно сообщить компилятору, что это тип.

+0

Нет 'typename' требует квалифицированного имени. –

+1

О да, мой плохой, 'BST ' - это требуемое квалифицированное имя. Извините за ошибку :) – Rerito

+0

Спасибо за ответ! Не могли бы вы подробнее рассказать о ключевом слове typename? Я немного смущен, когда нужно использовать его. Кроме того, после исправления синтаксических ошибок, я получаю много ошибок ссылок, которые я не могу прочитать ... они что-то вроде «ошибка LNK2019: неразрешенный внешний символ» private: void __thiscall BST :: printPreOrder (struct BST :: TreeNode *) "(? PrintPreOrder @? $ BST @ H @@ AAEXPAUTreeNode @ 1 @@ Z) ссылка в функции" public: void __thiscall BST :: printTree (int) "(? PrintTree @? $ BST @ H @@ QAEXH @ Z) ' – user3377437

1
#include <iostream> 
#include <stdlib.h> 

using namespace std; 

template<class T> 
class BST 
{ 
    struct TreeNode { 
     TreeNode* left; 
     TreeNode* right; 
     T value; 
    }; 

    //member functions 
    void destroyTree(TreeNode* leaf); 
    void insert(T key, TreeNode* leaf); 
    TreeNode* search(T key, TreeNode* leaf); 
    void printInOrder(TreeNode* leaf); 
    void printPreOrder(TreeNode* leaf); 
    void printPostOrder(TreeNode* leaf); 

    //memebr variables 
    TreeNode* root; 
public: 

    enum Traversal { INORDER, PREORDER, POSTORDER }; 
    BST(); 
    BST(T key); 
    ~BST(); 

    void insert(T key); 
    TreeNode* search(T key); 
    void printTree(T option); 
    void destroyTree(); 
}; 

template <class T> 
BST<T>::BST() 
{ 
    root = NULL; 
}; 

template <class T> 
BST<T>::BST(T key) 
{ 
    root = new TreeNode; 
    root->left = NULL; 
    root->right = NULL; 
    root->value = key; 
}; 

template <class T> 
BST<T>::~BST() 
{ 
    destroyTree(); 
}; 

template <class T> 
void BST<T>::destroyTree(TreeNode* leaf) 
{ 
    if (leaf->left != NULL) destroyTree(leaf->left); 
    if (leaf->right != NULL) destroyTree(leaf->right); 
    delete leaf; 
    leaf = nullptr; 
}; 

template <class T> 
void BST<T>::insert(T key, typename BST<T>::TreeNode* leaf) 
{ 
    if (leaf->value == key) 
    { 
     cout << "failed inserting node: duplicate item" << endl; 
     return; 
    } 
    else if (leaf->value < key) 
    { 
     if (leaf->right != NULL) insert(key, leaf->right); 
     else 
     { 
      BST<T>::TreeNode* newNode = new TreeNode; 
      newNode->left = NULL; 
      newNode->right = NULL; 
      newNode->value = key; 
      leaf->right = newNode; 
     } 
    } 
    else 
    { 
     if (leaf->left != NULL) insert(key, leaf->left); 
     else 
     { 
      BST<T>::TreeNode* newNode = new TreeNode; 
      newNode->left = NULL; 
      newNode->right = NULL; 
      newNode->value = key; 
      leaf->left = newNode; 
     } 
    } 
}; 

template <class T> 
typename BST<T>::TreeNode* BST<T>::search(T key, typename BST<T>::TreeNode* leaf) 
{ 
    if (leaf == NULL) return NULL; 
    if (leaf->value == key) return leaf; 
    else if (leaf->vluae < key) return search(key, leaf->right); 
    else return search(key, leaf->left); 
}; 

template <class T> 
void printInOrder(typename BST<T>::TreeNode* leaf) 
{ 
    if (leaf->left != NULL) printInOrder(leaf->left); 
    cout << leaf->value << " "; 
    if (leaf->right != NULL) printInOrder(leaf->right); 
}; 

template <class T> 
void printPreOrder(typename BST<T>::TreeNode* leaf) 
{ 
    cout << leaf->value << " "; 
    if (leaf->left != NULL) printPreOrder(leaf->left); 
    if (leaf->right != NULL) printPreOrder(leaf->right); 
}; 

template <class T> 
void printPostOrder(typename BST<T>::TreeNode* leaf) 
{ 
    if (leaf->left != NULL) printPostOrder(leaf->left); 
    if (leaf->right != NULL) printPostOrder(leaf->right); 
    cout << leaf->value << " "; 
}; 

template <class T> 
void BST<T>::insert(T key) 
{ 
    if (this->root == NULL) 
    { 
     this->root = new TreeNode; 
     this->root->left = NULL; 
     this->root->right = NULL; 
     this->root->value = key; 
    } 
    else insert(key, root); 
}; 

template <class T> 
typename BST<T>::TreeNode* BST<T>::search(T key) 
{ 
    search(key, this->root); 
}; 

template <class T> 
void BST<T>::printTree(T option) 
{ 
    switch (option) 
    { 
     case BST<T>::INORDER: 
      printInOrder(this->root); 
      cout << endl; 
      break; 
     case BST<T>::POSTORDER: 
      printPostOrder(this->root); 
      cout << endl; 
      break; 
     case BST<T>::PREORDER: 
      printPreOrder(this->root); 
      cout << endl; 
      break; 
    } 
}; 

template <class T> 
void BST<T>::destroyTree() 
{ 
    destroyTree(this->root); 
}; 

Должно работать сейчас, но была полна мелких ошибок, таких как: TreeNode newNode = new TreeNode;, template <class T> void insert вместо template <class T> void BST<T>::insert

+0

Спасибо за помощь! – user3377437

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