2014-04-24 31 views
1

我想基於我的教授給出的代碼來製作二叉樹,但Xcode一直告訴我「root」未定義binarySearchTree.h即使它已經在binaryTree.h中定義。誰能告訴我這有什麼問題?C++使用未聲明的標識符錯誤,當它已被其他地方聲明

這是binarySearch樹文件。

//Header File Binary Search Tree 
#ifndef H_binaryTree 
#define H_binaryTree 

#include <iostream> 

using namespace std; 

    //Definition of the Node 
template <class elemType> 
struct nodeType 
{ 
    elemType info; 
    nodeType<elemType> *lLink; 
    nodeType<elemType> *rLink; 
}; 

    //Definition of the class 
template <class elemType> 
class binaryTreeType 
{ 
public: 
    const binaryTreeType<elemType>& operator= 
       (const binaryTreeType<elemType>&); 
     //Overload the assignment operator. 

    bool isEmpty() const; 
     //Function to determine whether the binary tree is empty. 
     //Postcondition: Returns true if the binary tree is empty; 
     //    otherwise, returns false. 

    void inorderTraversal() const; 
     //Function to do an inorder traversal of the binary tree. 
     //Postcondition: Nodes are printed in inorder sequence. 

    void preorderTraversal() const; 
     //Function to do a preorder traversal of the binary tree. 
     //Postcondition: Nodes are printed in preorder sequence. 

    void postorderTraversal() const; 
     //Function to do a postorder traversal of the binary tree. 
     //Postcondition: Nodes are printed in postorder sequence. 

    int treeHeight() const; 
     //Function to determine the height of a binary tree. 
     //Postcondition: Returns the height of the binary tree. 

    int treeNodeCount() const; 
     //Function to determine the number of nodes in a 
     //binary tree. 
     //Postcondition: Returns the number of nodes in the 
     //    binary tree. 

    int treeLeavesCount() const; 
     //Function to determine the number of leaves in a 
     //binary tree. 
     //Postcondition: Returns the number of leaves in the 
     //    binary tree. 

    void destroyTree(); 
     //Function to destroy the binary tree. 
     //Postcondition: Memory space occupied by each node 
     //    is deallocated. 
     //    root = NULL; 

    virtual bool search(const elemType& searchItem) const = 0; 
     //Function to determine if searchItem is in the binary 
     //tree. 
     //Postcondition: Returns true if searchItem is found in 
     //    the binary tree; otherwise, returns 
     //    false. 

    virtual void insert(const elemType& insertItem) = 0; 
     //Function to insert insertItem in the binary tree. 
     //Postcondition: If there is no node in the binary tree 
     //    that has the same info as insertItem, a 
     //    node with the info insertItem is created 
     //    and inserted in the binary search tree. 

    virtual void deleteNode(const elemType& deleteItem) = 0; 
     //Function to delete deleteItem from the binary tree 
     //Postcondition: If a node with the same info as 
     //    deleteItem is found, it is deleted from 
     //    the binary tree. 
     //    If the binary tree is empty or 
     //    deleteItem is not in the binary tree, 
     //    an appropriate message is printed. 

    binaryTreeType(const binaryTreeType<elemType>& otherTree); 
     //Copy constructor 

    binaryTreeType(); 
     //Default constructor 

    ~binaryTreeType(); 
     //Destructor 

protected: 
    nodeType<elemType> *root; 

private: 
    void copyTree(nodeType<elemType>* &copiedTreeRoot, 
        nodeType<elemType>* otherTreeRoot); 
     //Makes a copy of the binary tree to which 
     //otherTreeRoot points. 
     //Postcondition: The pointer copiedTreeRoot points to 
     //    the root of the copied binary tree. 

    void destroy(nodeType<elemType>* &p); 
     //Function to destroy the binary tree to which p points. 
     //Postcondition: Memory space occupied by each node, in 
     //    the binary tree to which p points, is 
     //    deallocated. 
     //    p = NULL; 

    void inorder(nodeType<elemType> *p) const; 
     //Function to do an inorder traversal of the binary 
     //tree to which p points. 
     //Postcondition: Nodes of the binary tree, to which p 
     //    points, are printed in inorder sequence. 

    void preorder(nodeType<elemType> *p) const; 
     //Function to do a preorder traversal of the binary 
     //tree to which p points. 
     //Postcondition: Nodes of the binary tree, to which p 
     //    points, are printed in preorder 
     //    sequence. 

    void postorder(nodeType<elemType> *p) const; 
     //Function to do a postorder traversal of the binary 
     //tree to which p points. 
     //Postcondition: Nodes of the binary tree, to which p 
     //    points, are printed in postorder 
     //    sequence. 

    int height(nodeType<elemType> *p) const; 
     //Function to determine the height of the binary tree 
     //to which p points. 
     //Postcondition: Height of the binary tree to which 
     //    p points is returned. 

    int max(int x, int y) const; 
     //Function to determine the larger of x and y. 
     //Postcondition: Returns the larger of x and y. 

    int nodeCount(nodeType<elemType> *p) const; 
     //Function to determine the number of nodes in 
     //the binary tree to which p points. 
     //Postcondition: The number of nodes in the binary 
     //    tree to which p points is returned. 

    int leavesCount(nodeType<elemType> *p) const; 
     //Function to determine the number of leaves in 
     //the binary tree to which p points 
     //Postcondition: The number of leaves in the binary 
     //    tree to which p points is returned. 
}; 

    //Definition of member functions 

template <class elemType> 
binaryTreeType<elemType>::binaryTreeType() 
{ 
    root = NULL; 
} 

template <class elemType> 
bool binaryTreeType<elemType>::isEmpty() const 
{ 
    return (root == NULL); 
} 

template <class elemType> 
void binaryTreeType<elemType>::inorderTraversal() const 
{ 
    inorder(root); 
} 

template <class elemType> 
void binaryTreeType<elemType>::preorderTraversal() const 
{ 
    preorder(root); 
} 

template <class elemType> 
void binaryTreeType<elemType>::postorderTraversal() const 
{ 
    postorder(root); 
} 

template <class elemType> 
int binaryTreeType<elemType>::treeHeight() const 
{ 
    return height(root); 
} 

template <class elemType> 
int binaryTreeType<elemType>::treeNodeCount() const 
{ 
    return nodeCount(root); 
} 

template <class elemType> 
int binaryTreeType<elemType>::treeLeavesCount() const 
{ 
    return leavesCount(root); 
} 

template <class elemType> 
void binaryTreeType<elemType>::copyTree 
         (nodeType<elemType>* &copiedTreeRoot, 
         nodeType<elemType>* otherTreeRoot) 
{ 
    if (otherTreeRoot == NULL) 
     copiedTreeRoot = NULL; 
    else 
    { 
     copiedTreeRoot = new nodeType<elemType>; 
     copiedTreeRoot->info = otherTreeRoot->info; 
     copyTree(copiedTreeRoot->lLink, otherTreeRoot->lLink); 
     copyTree(copiedTreeRoot->rLink, otherTreeRoot->rLink); 
    } 
} //end copyTree 

template <class elemType> 
void binaryTreeType<elemType>::inorder 
           (nodeType<elemType> *p) const 
{ 
    if (p != NULL) 
    { 
     inorder(p->lLink); 
     cout << p->info << " "; 
     inorder(p->rLink); 
    } 
} 

template <class elemType> 
void binaryTreeType<elemType>::preorder 
           (nodeType<elemType> *p) const 
{ 
    if (p != NULL) 
    { 
     cout << p->info << " "; 
     preorder(p->lLink); 
     preorder(p->rLink); 
    } 
} 

template <class elemType> 
void binaryTreeType<elemType>::postorder 
           (nodeType<elemType> *p) const 
{ 
    if (p != NULL) 
    { 
     postorder(p->lLink); 
     postorder(p->rLink); 
     cout << p->info << " "; 
    }  
} 

    //Overload the assignment operator 
template <class elemType> 
const binaryTreeType<elemType>& binaryTreeType<elemType>:: 
     operator=(const binaryTreeType<elemType>& otherTree) 
{ 
    if (this != &otherTree) //avoid self-copy 
    { 
     if (root != NULL) //if the binary tree is not empty, 
          //destroy the binary tree 
      destroy(root); 

     if (otherTree.root == NULL) //otherTree is empty 
      root = NULL; 
     else 
      copyTree(root, otherTree.root); 
    }//end else 

    return *this; 
} 

template <class elemType> 
void binaryTreeType<elemType>::destroy(nodeType<elemType>* &p) 
{ 
    if (p != NULL) 
    { 
     destroy(p->lLink); 
     destroy(p->rLink); 
     delete p; 
     p = NULL; 
    } 
} 

template <class elemType> 
void binaryTreeType<elemType>::destroyTree() 
{ 
    destroy(root); 
} 

    //copy constructor 
template <class elemType> 
binaryTreeType<elemType>::binaryTreeType 
       (const binaryTreeType<elemType>& otherTree) 
{ 
    if (otherTree.root == NULL) //otherTree is empty 
     root = NULL; 
    else 
     copyTree(root, otherTree.root); 
} 

    //Destructor 
template <class elemType> 
binaryTreeType<elemType>::~binaryTreeType() 
{ 
    destroy(root); 
} 

template<class elemType> 
int binaryTreeType<elemType>::height 
          (nodeType<elemType> *p) const 
{ 
    if (p == NULL) 
     return 0; 
    else 
     return 1 + max(height(p->lLink), height(p->rLink)); 
} 

template <class elemType> 
int binaryTreeType<elemType>::max(int x, int y) const 
{ 
    if (x >= y) 
     return x; 
    else 
     return y; 
} 

template <class elemType> 
int binaryTreeType<elemType>::nodeCount(nodeType<elemType> *p) const 
{ 
    cout << "Write the definition of the function nodeCount." 
     << endl; 

    return 0; 
} 

template <class elemType> 
int binaryTreeType<elemType>::leavesCount(nodeType<elemType> *p) const 
{ 
    cout << "Write the definition of the function leavesCount." 
     << endl; 

    return 0; 
} 

#endif 

這裏的地方我收到約根是未定義的錯誤binarySearchTree.h文件。

//Header File Binary Search Tree 

#ifndef H_binarySearchTree 
#define H_binarySearchTree 
#include <iostream> 
#include "binaryTree.h" 

using namespace std; 

template <class elemType> 
class bSearchTreeType: public binaryTreeType<elemType> 
{ 
public: 
    bool search(const elemType& searchItem) const; 
     //Function to determine if searchItem is in the binary 
     //search tree. 
     //Postcondition: Returns true if searchItem is found in 
     //    the binary search tree; otherwise, 
     //    returns false. 

    void insert(const elemType& insertItem); 
     //Function to insert insertItem in the binary search tree. 
     //Postcondition: If there is no node in the binary search 
     //    tree that has the same info as 
     //    insertItem, a node with the info 
     //    insertItem is created and inserted in the 
     //    binary search tree. 

    void deleteNode(const elemType& deleteItem); 
     //Function to delete deleteItem from the binary search tree 
     //Postcondition: If a node with the same info as deleteItem 
     //    is found, it is deleted from the binary 
     //    search tree. 
     //    If the binary tree is empty or deleteItem 
     //    is not in the binary tree, an appropriate 
     //    message is ptinted. 

private: 
    void deleteFromTree(nodeType<elemType>* &p); 
     //Function to delete the node to which p points is 
     //deleted from the binary search tree. 
     //Postcondition: The node to which p points is deleted 
     //    from the binary search tree. 
}; 


template <class elemType> 
bool bSearchTreeType<elemType>::search 
        (const elemType& searchItem) const 
{ 
    nodeType<elemType> *current; 
    bool found = false; 

    if (root == NULL) 
     cout << "Cannot search an empty tree." << endl; 
    else 
    { 
     current = root; 

     while (current != NULL && !found) 
     { 
      if (current->info == searchItem) 
       found = true; 
      else if (current->info > searchItem) 
       current = current->lLink; 
      else 
       current = current->rLink; 
     }//end while 
    }//end else 

    return found; 
}//end search 

template <class elemType> 
void bSearchTreeType<elemType>::insert 
       (const elemType& insertItem) 
{ 
    nodeType<elemType> *current; //pointer to traverse the tree 
    nodeType<elemType> *trailCurrent; //pointer behind current 
    nodeType<elemType> *newNode; //pointer to create the node 

    newNode = new nodeType<elemType>; 
    newNode->info = insertItem; 
    newNode->lLink = NULL; 
    newNode->rLink = NULL; 

    if (root == NULL) 
     root = newNode; 
    else 
    { 
     current = root; 

     while (current != NULL) 
     { 
      trailCurrent = current; 

      if (current->info == insertItem) 
      { 
       cout << "The item to be inserted is already "; 
       cout << "in the tree -- duplicates are not " 
        << "allowed." << endl; 
       return; 
      } 
      else if (current->info > insertItem) 
       current = current->lLink; 
      else 
       current = current->rLink; 
     }//end while 

     if (trailCurrent->info > insertItem) 
      trailCurrent->lLink = newNode; 
     else 
      trailCurrent->rLink = newNode; 
    } 
}//end insert 

template <class elemType> 
void bSearchTreeType<elemType>::deleteNode 
           (const elemType& deleteItem) 
{ 
    nodeType<elemType> *current; //pointer to traverse the tree 
    nodeType<elemType> *trailCurrent; //pointer behind current 
    bool found = false; 

    if (root == NULL) 
     cout << "Cannot delete from an empty tree." 
      << endl; 
    else 
    { 
     current = root; 
     trailCurrent = root; 

     while (current != NULL && !found) 
     { 
      if (current->info == deleteItem) 
       found = true; 
      else 
      { 
       trailCurrent = current; 

       if (current->info > deleteItem) 
        current = current->lLink; 
       else 
        current = current->rLink; 
      } 
     }//end while 

     if (current == NULL) 
      cout << "The item to be deleted is not in the tree." 
       << endl; 
     else if (found) 
     { 
      if (current == root) 
       deleteFromTree(root); 
      else if (trailCurrent->info > deleteItem) 
       deleteFromTree(trailCurrent->lLink); 
      else 
       deleteFromTree(trailCurrent->rLink); 
     } 
     else 
      cout << "The item to be deleted is not in the tree." 
       << endl; 
    } 
} //end deleteNode 

template <class elemType> 
void bSearchTreeType<elemType>::deleteFromTree 
           (nodeType<elemType>* &p) 
{ 
    nodeType<elemType> *current; //pointer to traverse the tree 
    nodeType<elemType> *trailCurrent; //pointer behind current 
    nodeType<elemType> *temp;  //pointer to delete the node 

    if (p == NULL) 
     cout << "Error: The node to be deleted is NULL." 
      << endl; 
    else if (p->lLink == NULL && p->rLink == NULL) 
    { 
     temp = p; 
     p = NULL; 
     delete temp; 
    } 
    else if (p->lLink == NULL) 
    { 
     temp = p; 
     p = temp->rLink; 
     delete temp; 
    } 
    else if (p->rLink == NULL) 
    { 
     temp = p; 
     p = temp->lLink; 
     delete temp; 
    } 
    else 
    { 
     current = p->lLink; 
     trailCurrent = NULL; 

     while (current->rLink != NULL) 
     { 
      trailCurrent = current; 
      current = current->rLink; 
     }//end while 

     p->info = current->info; 

     if (trailCurrent == NULL) //current did not move; 
           //current == p->lLink; adjust p 
      p->lLink = current->lLink; 
     else 
      trailCurrent->rLink = current->lLink; 

     delete current; 
    }//end else 
} //end deleteFromTree 

#endif 

如果有人能告訴我這裏出了什麼問題,我將非常感激。

+0

你能發佈確切的錯誤信息嗎? – aruisdante

+0

準確地說,「使用未聲明的標識符'root'」。 – VinnyDakid

回答

6

這是一個常見問題。

請參閱C++ FAQ條目"Why am I getting errors when my template-derived-class uses a member it inherits from its template-base-class? "

引述常見問題:

」編譯器看起來不是依賴基類(如B<T>)尋找非依賴的名字(例如f)時。 」

依賴性基類是一個基類,取決於一些模板參數。編譯器無法知道基類沒有或將不專用於模板參數的任何類型或值。因此規則是它可以一味地假設事物存在,它必須是告訴假設。

的FAQ列出了以下解決方法(參考FAQ ’自己的例子):

•呼叫更改從f()this->f()。由於this總是隱式地依賴於模板,所以this->f是依賴的,因此延遲查找直到模板實際實例化,此時考慮所有基類。

•在撥打f()之前使用B<T>::f;插入。

•將呼叫從f()更改爲B<T>::f()。但請注意,如果f()是虛擬的,這可能不會給你想要的,因爲它禁止虛擬調度機制。

在你的情況下,你’重新引用數據項而不是函數,但同樣適用。

+0

避免像這樣的東西是爲什麼我總是在引用類的成員/方法時使用''this''。這需要更長的時間,但至少你總是清楚你所引用的內容,無論是你自己/其他程序員還是編譯器。 – aruisdante

+0

我想我明白這是什麼意思,但我不確定如何在我的代碼中實際執行該操作。我需要在這裏做什麼,因爲它在許多不同的位置給出了錯誤? – VinnyDakid

+0

只需將所有''root''發生改爲''this-> root'' – aruisdante