0

I am currently writing the code for my c++ class in Visual Studio 2022 and it is meant to be a class for binaryTreeType and binarySearchTreeType. After finishing most of the code for both classes (binaryTreeType and binarySearchTreeType) I am now getting two errors in my binarySearchTreeType class. My teacher wanted me to complete all function definitions in the same header files for each class and not separate them with .cpp file.

C2065: 'root': undeclared identifier C3861: 'root': identifier not found.

#pragma once
#include <iostream>

using namespace std;

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

//binaryTreeType class definition
template <class elemType>
class binaryTreeType
{
public:
    const binaryTreeType<elemType>& operator=                       //Ovearloaded assignment operator
        (const binaryTreeType<elemType>&);

    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 enumber 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 = nullptr

    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 binary tree; otherwise; returns fase

    virtual void insert(const elemType& insertItem) = 0;            //Function to insert inserItem 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 inserItem is created and inserted in the binary 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 found, 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,              //Makes a copy of the binary tree to which otherTreeRoot points
        nodeType<elemType>* otherTreeRoot);                         //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 = nullptr

    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: returns the number of nodes in the binary tree to which p points

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

template <class elemType>
int binaryTreeType<elemType>::nodeCount(nodeType<elemType>* p) const
{
    if (p == nullptr)
        return 0;
    else
    {
        int leftCount = nodeCount(p->lLink);
        int rightCount = nodeCount(p->rLink);
        return leftCount + rightCount + 1;
    }
}

template <class elemType>
int binaryTreeType<elemType>::leavesCount(nodeType<elemType>* p) const
{
    if (p == nullptr)
        return 0;
    else if (p->lLink == nullptr && p->rLink == nullptr)
        return 1;
    else
    {
        int leftCount = leavesCount(p->left);
        int rightCount = leavesCount(p->right);
        return leftCount + rightCount;
    }
}

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

template <class elemType>
binaryTreeType<elemType>::binaryTreeType()
{
    cout << "binaryTreeType.h,      Lab 4-1     Lab 4-1.cpp" << endl << endl;
    root = nullptr;
}

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>::inorder(nodeType<elemType>* p) const
{
    if (p == nullptr) return;
    {
        inorder(p->lLink);
        cout << p->info << " ";
        inorder(p->rLink);
    }
}

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

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

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

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

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

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

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

template <class elemType>
binaryTreeType<elemType>::binaryTreeType(const binaryTreeType<elemType>& otherTree)
{
    if (otherTree.root == nullptr)
        root = nullptr;
    else
        copyTree(root, otherTree.root);
}

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

template <class elemType>
const binaryTreeType<elemType>& binaryTreeType<elemType>::operator=(const binaryTreeType<elemType>& otherTree)
{
    if (this != &otherTree)
    {
        if (root != nullptr)
            destroy(root);
        if (otherTree.root == nullptr)
            root = nullptr;
        else
            copyTree(root, otherTree.root);
    }
    return *this;
}

#include <iostream>
#include "binaryTreeType.h"
#pragma once

using namespace std;

template <class elemType>
class binarySearchTreeType: 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 in the binary 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 search tree is empty or deleteItem is not in the binary 
                                                                        //search tree, an appropriate message is printed

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 binarky search tree
};

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

    if (root == nullptr)
        cout << "Cannot search an empty tree." << endl;
    else
    {
        current = root;
        while (current != nullptr && !found)
        {
            if (current->info == searchItem)
                found = true;
            else if (current->info > searchItem)
                current = current->lLink;
            else current = current->rLink;
        }
    }
    return found;
}

template <class elemType>
void binarySearchTreeType<elemType>::insert(const elemType& insertItem)
{
    nodeType<elemType>* current;
    nodeType<elemType>* trailCurrent = nullptr;
    nodeType<elemType>* newNode;

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

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

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

template <class elemType>
void binarySearchTreeType<elemType>::deleteFromTree(nodeType<elemType>*& p)
{
    nodeType<elemType>* current;
    nodeType<elemType>* trailCurrent;
    nodeType<elemType>* temp;

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

        while (current->rLink != nullptr)
        {
            trailCurrent = current;
            current = current->rLink;
        }

        p->info = current->info;

        if (trailCurrent == nullptr)
            p->lLink = current->lLink;
        else
            trailCurrent->rLink = current->lLink;
        delete current;
    }
}

template <class elemType>
void binarySearchTreeType<elemType>::deleteNode(const elemType& deleteItem)
{
    nodeType<elemType>* current;
    nodeType<elemType>* trailCurrent;
    bool found = false;

    if (root == nullptr)
        cout << "Cannot delete from an empty tree." << endl;

    else
    {
        current = root;
        trailCurrent = root;

        while (current != nullptr && !found)
        {
            if (current->info == deleteItem)
                found = true;
            else
            {
                trailCurrent = current;
                if (current->info > deleteItem)
                    current = current->lLink;
                else
                    current = current->rLink;
            }
        }


        if (current == nullptr)
            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;
    }
}

I am not sure why I am getting these errors as if I move the functions from binarySearchTreeType class to binaryTreeType class everything works fine. I have tried making new projects and copy the code into there to see if the files were corrupted and it still did not work. I also tried copy and pasting the program into codeblocks and I get the same errors when trying to compile and run the program. text

  • *My teacher wanted me to complete all function definitions in the same header files for each class and not separate them with .cpp file* - Very reasonable, [templates usually need to be defined in header file](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Yksisarvinen May 02 '23 at 08:30

0 Answers0