提问人:Isaac_G59 提问时间:7/7/2023 更新时间:7/7/2023 访问量:7
模板错误 C3857 和 C2989
Template errors C3857 and C2989
问:
我有一个基 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;
}
};
答: 暂无答案
评论