模板错误 C3857 和 C2989

Template errors C3857 and C2989

提问人:Isaac_G59 提问时间:7/7/2023 更新时间:7/7/2023 访问量:7

问:

我有一个基 BinaryTree 类,它为 Node 类型提供模板,以便我能够从它继承我的 AVLTree 类的一些功能。虽然当我在main中运行一些测试代码时,我收到了错误代码,表明存在“不允许多个模板参数列表”和“类模板已被声明为非类模板”的问题。

下面是我的 BinaryTree 类和 AVLTree 类的代码。我已经指出了标记这两条线的位置。

我曾尝试过向前申报,但无济于事。事实上,这导致了更多的错误。

AVLTree.h | V

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


template <class T>
struct AVLNode
{
    T mElement;
    AVLNode<T>* mpLeft;
    AVLNode<T>* mpRight;
    int mHeight;

    AVLNode(const T& element, AVLNode<T>* left, AVLNode<T>* right, int height = 0) 
        : mElement(element), mpLeft(left), mpRight(right), mHeight(height)  {};
    friend class AVLTree;

};

template <class T> //error message: class template has already been declared...
class AVLTree : public BinaryTree<T, AVLNode<T>> //multiple template parameter...      
{
private:
    const T ITEM_NOT_FOUND;
    const T& elementAt(AVLNode<T>* node) const
    {
        if (node == nullptr)
        {
            return ITEM_NOT_FOUND;
        }
        else
        {
            return node->mElement;
        }
    }

    void insert(const T& value, AVLNode<T>*& root)
    {
        if (root == nullptr)
        {
            root = new AVLNode<T>(value, nullptr, nullptr);
        }
        else if (value < root->mElement)
        {
            insert(value, root->mpLeft);
            if (height(root->mpLeft) - height(root->mpRight) == 2)
            {
                if (value < root->mpLeft->mElement)
                    rotateWithLeftChild(root);
                else
                    doubleRotateWithLeftChild(root);
            }
        }
        else if (value > root->mElement)
        {
            insert(value, root->mpRight);
            if (height(root->mpRight) - height(root->mpLeft) == 2)
            {
                if (value > root->mpRight->mElement)
                    rotateWithRightChild(root);
                else
                    doubleRotateWithRightChild(root);
            }
        }
        root->mHeight = max(height(root->mpLeft), height(root->mpRight)) + 1;
    }

    void remove(const T& value, AVLNode<T>*& root)
    {
        if (root == nullptr)
        {
            return;
        }
        if (value < root->mElement)
        {
            remove(value, root->mpLeft);
        }
        else if (value > root->mElement)
        {
            remove(value, root->mpRight);
        }
        else if (root->mpLeft != nullptr && root->mpRight != nullptr) // Two children
        {
            root->mElement = findMin(root->mpRight)->mElement;
            remove(root->mElement, root->mpRight);
        }
        else // one or no children
        {
            AVLNode<T>* oldNode = root;
            root = (root->mpLeft != nullptr) ? root->mpLeft : root->mpRight;
            delete oldNode;
        }

        if (root == nullptr)
        {
            return;
        }

        root->mHeight = max(height(root->mpLeft), height(root->mpRight)) + 1;

        if (height(root->mpLeft) - height(root->mpRight) == 2)  // Left side heavy
        {
            if (height(root->mpLeft->mpLeft) >= height(root->mpLeft->mpRight))
                rotateWithLeftChild(root);
            else
                doubleRotateWithLeftChild(root);
        }
        else if (height(root->mpRight) - height(root->mpLeft) == 2)  // Right side heavy
        {
            if (height(root->mpRight->mpRight) >= height(root->mpRight->mpLeft))
                rotateWithRightChild(root);
            else
                doubleRotateWithRightChild(root);
        }
    }

    AVLNode<T>* findMin(AVLNode<T>* node) const
    {
        if (node == nullptr)
        {
            return node;
        }

        while (node->mpLeft != nullptr)
        {
            node = node->mpLeft;
        }
        return node;
    }

    AVLNode<T>* findMax(AVLNode<T>* node) const
    {
        if (node == nullptr)
        {
            return node;
        }
        
        while (node->mpRight != nullptr)
        {
            node = node->mpRight;
        }
        return node;
    }

    AVLNode<T>* find(const T& value, AVLNode<T>* node) const
    {
        while (node != nullptr)
        {
            if (value < node->mElement)
            {
                node = node->mpRight;
            }
            
            else if (value > node->mElement)
            {
                node = node->mpLeft;
            }
            else
            {
                return node;
            }
        }

        return nullptr;
    }

    AVLNode<T>* clone(AVLNode<T>* node) const
    {
        if (node == nullptr)
        {
            return nullptr;
        }
        else
        {
            return new AVLNode<T>*(node->mElement, clone(node->mpLeft), clone(node->mpRight), node->height);
        }
    }

    int height(AVLNode<T>* root) const
    {
        return root == nullptr ? -1 : root->mHeight;
    }

    int max(int leftHandSide, int rightHandSide) const
    {
        return leftHandSide > rightHandSide ? leftHandSide : rightHandSide;
    }

    void rotateWithLeftChild(AVLNode<T>*& k2node) const
    {
        AVLNode<T>* k1node = k2node->mpLeft;
        k2node->mpLeft = k1node->mpRight;
        k1node->mpRight = k2node;
        k2node->mHeight = max(height(k2node->mpLeft), height(k2node->mpRight)) + 1;
        k1node->mHeight = max(height(k1node->mpLeft), k2node->mHeight) + 1;
        k2node = k1node;
    }

    void rotateWithRightChild(AVLNode<T>*& k1node) const
    {
        AVLNode<T>* k2node = k1node->mpRight;
        k1node->mpRight = k2node->mpLeft;
        k2node->mpLeft = k1node;
        k1node->mHeight = max(height(k1node->mpLeft), height(k1node->mpRight)) + 1;
        k2node->mHeight = max(height(k2node->mpRight), k1node->mHeight) + 1;
        k1node = k2node;
    }

    void doubleRotateWithLeftChild(AVLNode<T>*& k3node) const
    {
        rotateWithRightChild(k3node->mpLeft);
        rotateWithLeftChild(k3node);
    }

    void doubleRotateWithRightChild(AVLNode<T>*& k1node) const
    {
        rotateWithLeftChild(k1node->mpRight);
        rotateWithRightChild(k1node);
    }


public:

    AVLTree()
        : BinaryTree<T, AVLNode<T>>(), ITEM_NOT_FOUND(T())
    {
    }

    AVLTree(const T& notFound)
        : BinaryTree<T,AVLNode<T>>(nullptr), ITEM_NOT_FOUND(notFound) {};

    AVLTree(const AVLTree<T>& rightHandSide)
        : BinaryTree<T, AVLNode<T>>(nullptr), ITEM_NOT_FOUND(rightHandSide.ITEM_NOT_FOUND)
    {
        *this = rightHandSide;
    }

    ~AVLTree()
    {
        this->makeEmpty();
    }

    void insert(const T& value)
    {
        insert(value, AVLNode<T>*node);
    }

    void remove(const T& value)
    {
        remove(value, this->node);
    }

    const T& findMin() const
    {
        return elementAt(findMin(node));
    }

    const T& findMax() const
    {
        return elementAt(findMax(root));
    }

    const T& find(const T& value) const
    {
        return this->find(const T& value, AVLNode<T>* node);
    }

    void makeEmpty()
    {
        BinaryTree<T, AVLNode<T>>::makeEmpty();
    }

    bool isEmpty() const
    {
        BinaryTree<T, AVLNode<T>>::isEmpty();
    }

    void printTree() const
    {
        BinaryTree<T, AVLNode<T>>::printTree();
    }

    const AVLTree<T>& operator=(const AVLTree& rightHandside)
    {
        if (this != &rightHandside)
        {
            this->makeEmpty();
            BinaryTree<T>::setRoot(clone(rightHandside.BinaryTree<T>::getRoot()));
        }

        return *this;
    }

};

BinaryTree.h (二进制树.h) | V

#pragma once
#include <iostream>

template <class T>
struct Node
{
    T mData;
    Node<T>* mpLeft;
    Node<T>* mpRight;

    Node(const T& data) : mData(data), mpLeft(nullptr), mpRight(nullptr) {};
};

template <class T, typename NodeType = Node<T>>
class BinaryTree
{
private:
    Node<T>* mpRoot;
    void insert(const T& data, Node<T>*& node)
    {
        if (node == nullptr)
        {
            node = new Node<T>(data);
        }
        else if (data < node->mData)
        {
            insert(data, node->mpLeft);
        }
        else if (data > node->mData)
        {
            insert(data, node->mpRight);
        }
    }

    void remove(const T& data, Node<T>*& node)
    {
        if (node == nullptr)
        {
            return;
        }
        if (data < node->mData)
        {
            remove(data, node->mpLeft);
        }
        else if (data > node->mData)
        {
            remove(data, node->mpRight);
        }
        else if (node->mpLeft != nullptr && node->mpRight != nullptr)
        {
            node->mData = findMin(node->mpRight);
            remove(node->mData, node->mpRight);
        }
        else
        {
            Node<T>* tmp = node;
            node = (node->mpLeft != nullptr) ? node->mpLeft : node->mpRight;
            delete tmp;
        }
    }

    T findMin(const Node<T>* node) const
    {
        if (node->mpLeft == nullptr)
        {
            return node->mData;
        }
        else
        {
            return findMin(node->mpLeft);
        }
    }

    T findMax(const Node<T>* node) const
    {
        if (node->mpRight == nullptr)
        {
            return node->mData;
        }
        else
        {
            return findMax(node->mpRight);
        }
    }

    bool contains(const T& data, const Node<T>* node) const
    {
        if (node == nullptr)
        {
            return false;
        }
        else if (data < node->mData)
        {
            return contains(data, node->mpLeft);
        }
        else if (data > node->mData)
        {
            return contains(data, node->mpRight);
        }
        else
        {
            return true;
        }
    }

    void printTree(const Node<T>* node) const
    {
        if (node != nullptr)
        {
            printTree(node->mpLeft);
            std::cout << node->mData << std::endl;
            printTree(node->mpRight);
        }
    }

public:
    BinaryTree()
        : mpRoot(nullptr)
    {
    }

    BinaryTree(const BinaryTree& rhs)
        : mpRoot(nullptr)
    {
        mpRoot = clone(rhs.mpRoot);
    }


    ~BinaryTree()
    {
        makeEmpty(mpRoot);
    }

protected:
    // This function is used by the copy constructor to do a deep copy of the tree
    Node<T>* clone(Node<T>* rhsRoot) const {
        if (rhsRoot == nullptr)
            return nullptr;

        Node<T>* root = new Node<T> (rhsRoot->mData);
        root->mpLeft = clone(rhsRoot->mpLeft);
        root->mpRight = clone(rhsRoot->mpRight);
        return root;
    }

public:
    Node<T>* getRoot() const
    {
        return this->mpRoot;
    }

    void setRoot(Node<T>* node)
    {
        this->mpRoot = node;
    }

    void insert(const T& data)
    {
        this->insert(data, this->mpRoot);
    }

    void remove(const T& data)
    {
        this->remove(data, this->mpRoot);
    }

    T findMin() const
    {
        if (this->isEmpty())
        {
            throw std::runtime_error("The tree is empty.");
        }
        return this->findMin(this->mpRoot);
    }

    T findMax() const
    {
        if (this->isEmpty())
        {
            throw std::runtime_error("The tree is empty.");
        }
        return this->findMax(this->mpRoot);
    }

    bool contains(const T& data) const
    {
        return this->contains(data, this->mpRoot);
    }

    void printTree() const
    {
        if (this->isEmpty())
        {
            std::cout << "The tree is empty." << std::endl;
        }
        else
        {
            this->printTree(this->mpRoot);
            std::cout << std::endl;
        }
    }

    bool isEmpty() const
    {
        return this->mpRoot == nullptr;
    }

    void makeEmpty(Node<T>* node)
    {
        if (node != nullptr)
        {
            makeEmpty(node->mpLeft);
            makeEmpty(node->mpRight);
        }

        delete node;
    }
};
模板 继承 binary-tree avl-tree

评论


答: 暂无答案