2017-10-04 43 views
1

我要的是一個相當簡單的二叉搜索樹是通過模板標籤,允許將內所使用的所有數值數據,但我有一些比較討厭的問題,我沒有線索如何擺脫,如果任何人都可以幫助,將不勝感激。彈出對我的錯誤信息是「無效使用模板名'BST'沒有參數列表」 - 坦率地說,我不知道如何解決它。它發生在bst.cpp文件的第31,89,105,120,130,141行。鑑於我對二叉搜索樹的熟練程度不夠高,我寧願儘可能確定答案(即使提及確切地在哪裏以及需要改變什麼):C++模板二叉搜索樹 - 參數列表錯誤

Main.cpp的

#include <iostream> 
#include "bst.h" 

using namespace std; 

int main() 
{ 

    BST <int> tree; 
    tree.insert(8); 
    tree.insert(25); 
    tree.insert(99); 
    tree.insert(20); 
    tree.insert(25); 
    tree.insert(20); 
    tree.insert(2); 
    tree.insert(89); 
    tree.insert(15); 
    tree.insert(10); 
    tree.insert(30); 
    tree.insert(50); 
    tree.displayorder(); 



    int number; 

    int Inputnumber; 
    while (true){ 
     cout << "Choose what you want to do: " << endl << "1# Insert" << endl << "2# Display Orders" << endl << "3# Search" << endl << "4# Delete" << endl << endl << endl; 
     cin >> Inputnumber; 
     if (Inputnumber==1){ 
      cout << endl << "Enter the number you want inserted: "; 
      cin >> number; 
      tree.insert(number); 
      cout << endl << endl << endl; 
     } 
     if (Inputnumber==2){ 
      cout<<"Display Orders: " << endl; 
      tree.displayorder(); 
      cout << endl << endl << endl; 
     } 

     if (Inputnumber==3){ 
      cout<<"Enter the number you want to search for: "; 
      cin >> number; 
      tree.search(number); 
      cout << endl << endl << endl; 
     } 
     if (Inputnumber==4){ 
      cout << "Enter the number you want to remove: "; 
      cin >> number; 
      tree.remove(number); 
      cout << endl << endl << endl; 
     } 
    } 
} 

BST.cpp

#include <iostream> 
#include "bst.h" 

using namespace std; 

template <class T> 
void BST<T>::preorder(node* tree) 
{ 
    if(tree == NULL){ 
     return; 
    } 
    cout << tree->data << " "; 
    inorder(tree->left); 
    inorder(tree->right); 
} 



template <class T> 
void BST<T>::postorder(node* tree) 
{ 
    if(tree == NULL){ 
     return; 
    } 
    inorder(tree->left); 
    inorder(tree->right); 
    cout << tree->data << " "; 
} 

template <typename T> 
BST::node* BST<T>::find(node* tree, T x)  //ERROR HERE 
{ 
    if(tree == NULL) 
     return NULL; 
    else if(x < tree->data) 
     return find(tree->left, x); 
    else if(x > tree->data) 
     return find(tree->right, x); 
    else 
     return tree; 
} 
template <typename T> 
BST<T>::BST() 
{ 
    root = NULL; 
} 

template <typename T> 
BST<T>::~BST() 
{ 
    root = makeEmpty(root); 
} 

template <class T> 
void BST<T>::insert(T x) 
{ 
    root = insert(x, root); 
} 

template <class T> 
void BST<T>::remove(T x) 
{ 
    root = remove(x, root); 
} 

template <class T> 
void BST<T>::displayorder() 
{ 
    inorder(root); 
    cout << endl; 
    preorder(root); 
    cout << endl; 
    postorder(root); 
    cout << endl << endl; 
} 

template <class T> 
void BST<T>::search(T x) 
{ 
    if(root = find(root, x)){ 
     cout << endl << "Found!" << endl; 
    } 
    else{ 
     cout << endl << "Not Found!" << endl; 
    } 
} 

template <class T> 
BST::node* BST<T>::makeEmpty(node* tree)  //ERROR HERE 
{ 
    if(tree == NULL) 
     return NULL; 
    { 
     makeEmpty(tree->left); 
     makeEmpty(tree->right); 
     delete tree; 
    } 
    return NULL; 
} 




template <class T> 
BST::node* BST<T>::insert(T x, node* tree)  //ERROR HERE 
{ 
    if(tree == NULL) 
    { 
     tree = new node; 
     tree->data = x; 
     tree->left = tree->right = NULL; 
    } 
    else if(x < tree->data) 
     tree->left = insert(x, tree->left); 
    else if(x >= tree->data) 
     tree->right = insert(x, tree->right); 
    return tree; 
} 

BST::node* BST::findMin(node* tree)    //ERROR HERE 
{ 
    if(tree == NULL) 
     return NULL; 
    else if(tree->left == NULL) 
     return tree; 
    else 
     return findMin(tree->left); 
} 

BST::node* BST::findMax(node* tree)    //ERROR HERE 
{ 
    if(tree == NULL) 
     return NULL; 
    else if(tree->right == NULL) 
     return tree; 
    else 
     return findMax(tree->right); 
} 

template <typename T> 
BST::node* BST<T>::remove(T x, node* tree)  //ERROR HERE 
{ 
    node* temp; 
    if(tree == NULL) 
     return NULL; 
    else if(x < tree->data) 
     tree->left = remove(x, tree->left); 
    else if(x > tree->data) 
     tree->right = remove(x, tree->right); 
    else if(tree->left && tree->right) 
    { 
     temp = findMin(tree->right); 
     tree->data = temp->data; 
     tree->right = remove(tree->data, tree->right); 
    } 
    else 
    { 
     temp = tree; 
     if(tree->left == NULL) 
      tree = tree->right; 
     else if(tree->right == NULL) 
      tree = tree->left; 
     delete temp; 
    } 

    return tree; 
} 

template <class T> 
void BST<T>::inorder(node* tree) 
{ 
    if(tree == NULL){ 
     return; 
    } 
    inorder(tree->left); 
    cout << tree->data << " "; 
    inorder(tree->right); 
} 

BST.h

#ifndef BST_H 
#define BST_H 


template <class T> 
class BST 
{ 
    struct node 
    { 
     T data; 
     node* left; 
     node* right; 
    }; 

    node* root; 

    node* makeEmpty(node* tree); 

    node* insert(T x, node* tree); 

    node* findMin(node* tree); 

    node* findMax(node* tree); 

    node* remove(T x, node* tree); 

    void inorder(node* tree); 

    void preorder(node* tree); 



    void postorder(node* tree); 


public: 
    BST(); 

    ~BST(); 


    node* find(node* tree, T x); 

    void insert(T x); 

    void remove(T x); 

    void displayorder(); 

    void search(T x); 
}; 

#endif // BST_H 
+6

你應該花一些時間閱讀[爲什麼模板只能在頭文件中實現?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file)會讓你免於問另一個問題這個代碼很快就會與此代碼相關。 –

+0

你知道std :: set嗎? – 2017-10-04 11:51:05

回答

3

例如,在

BST::node* BST<T>::find(node* tree, T x) 

您忘記了<T>組件的第一BST

應該

// vvv 
BST<T>::node* BST<T>::find(node* tree, T x) 

所有其他錯誤都是相同類型的。

3

像你顯然使用BST類模板是不是一個類型。這是創建類類型的祕訣。什麼錯誤消息是想告訴大家的是,(幾乎)任何地方,你使用的名稱BST,你需要後立即提供內部<尖括號>模板參數。

例如,在

template <class T> 
BST::node* BST<T>::makeEmpty(node* tree)  //ERROR HERE 

編譯器抱怨的BST在返回類型的第一個實例,而不是一個正確地指定BST<T>作爲類型。這可能應該是:

template <class T> 
BST<T>::node* BST<T>::makeEmpty(node* tree) 

[這個一般規則至少有兩個例外。一個是單獨模板的名稱可以用作另一個模板的模板參數,該模板需要模板而不是類型或值。

另一個稱爲「注入類名」:在類模板的範圍內(包括類模板成員),可以只使用模板的名稱作爲「當前」特化的別名。在該範圍內

template <class T> 
auto BST<T>::makeEmpty(node* tree) -> BST::node* 

在上面,因爲返回類型現在正值BST<T>::之後而不是之前,現在是:

所以其實你也可以使用一個尾隨返回類型和做因此你可以使用BST作爲BST<T>的別名。]