我目前正在开展一个学校项目。赋值是在给定相应头文件的情况下编写模板化二叉搜索树的实现。
我的问题是,由于它是模板化的,我不确定在插入或查找时如何对数据项进行比较。
这是头文件:
template < typename DataType, class KeyType > // DataType : tree data item
class BSTree // KeyType : key field
{
public:
// Constructor
BSTree (); // Default constructor
BSTree ( const BSTree<DataType,KeyType>& other ); // Copy constructor
BSTree& operator= ( const BSTree<DataType,KeyType>& other );
// Overloaded assignment operator
// Destructor
~BSTree ();
// Binary search tree manipulation operations
void insert ( const DataType& newDataItem ); // Insert data item
bool retrieve ( const KeyType& searchKey, DataType& searchDataItem ) const;
// Retrieve data item
bool remove ( const KeyType& deleteKey ); // Remove data item
void writeKeys () const; // Output keys
void clear (); // Clear tree
// Binary search tree status operations
bool isEmpty () const; // Tree is empty
// !! isFull() has been retired. Not very useful in a linked structure.
// Output the tree structure -- used in testing/debugging
void showStructure () const;
// In-lab operations
int getHeight () const; // Height of tree
int getCount () const; // Number of nodes in tree
void writeLessThan ( const KeyType& searchKey ) const; // Output keys < searchKey
protected:
class BSTreeNode // Inner class: facilitator for the BSTree class
{
public:
// Constructor
BSTreeNode ( const DataType &nodeDataItem, BSTreeNode *leftPtr, BSTreeNode *rightPtr );
// Data members
DataType dataItem; // Binary search tree data item
BSTreeNode *left, // Pointer to the left child
*right; // Pointer to the right child
};
// Recursive helpers for the public member functions -- insert
// prototypes of these functions here.
void showHelper ( BSTreeNode *p, int level ) const;
// Data member
BSTreeNode *root; // Pointer to the root node
};
有问题的功能是insert()。
我有以下代码:
template <typename DataType, class KeyType>
void BSTree< DataType, KeyType>::insert(const DataType& newDataItem)
{
if(isEmpty())
{
root = new BSTreeNode(newDataItem, NULL, NULL);
}
else
{
BSTreeNode *ptr = root;
while(ptr != NULL)
{
if((*ptr)>dataItem > newDataItem)
{
ptr = ptr->left;
}
else if((*ptr).dataItem < newDataItem)
{
ptr = ptr->right;
}
}
ptr = new BSTreeNode(newDataItem, NULL, NULL);
}
}
我收到以下错误:
44 E:\School\302\Labs\7\BSTree.cpp no match for 'operator>' in 'ptr->BSTree<TestData, int>::BSTreeNode::dataItem > newDataItem'
49 E:\School\302\Labs\7\BSTree.cpp no match for 'operator<' in 'ptr->BSTree<TestData, int>::BSTreeNode::dataItem < newDataItem'
我该如何处理?我是否需要编写重载运算符,如果是,我该如何开始?
这是调用insert的地方:
class TestData
{
public:
void setKey ( int newKey )
{ keyField = newKey; } // Set the key
int getKey () const
{ return keyField; } // Returns the key
private:
int keyField; // Key for the data item
};
int main()
{
BSTree<TestData,int> testTree; // Test binary search tree
TestData testData; // Binary search tree data item
int inputKey; // User input key
char cmd; // Input command
print_help();
do
{
testTree.showStructure(); // Output tree
cout << endl << "Command: "; // Read command
cin >> cmd;
if ( cmd == '+' || cmd == '?' ||
cmd == '-' || cmd == '<' )
cin >> inputKey;
switch ( cmd )
{
case 'P' : case 'p' :
print_help();
break;
case '+' : // insert
testData.setKey(inputKey);
cout << "Insert : key = " << testData.getKey()
<< endl;
testTree.insert(testData);
break;
}
我没有包含交换机的其余部分,因为示例不需要它。
我假设问题是因为我正在比较两种不同的数据类型或尝试过。我该如何解决这个问题?
我用以下代码解决了我的问题:
template <typename DataType, class KeyType>
void BSTree< DataType, KeyType>::insert(const DataType& newDataItem)
{
BSTreeNode* temp = new BSTreeNode(newDataItem, NULL, NULL);
if(isEmpty())
{
root = temp;
}
else
{
BSTreeNode* ptr = root;
while(ptr != NULL)
{
if(ptr > temp)
{
ptr = ptr->left;
}
else
{
ptr = ptr->right;
}
}
ptr = temp;
}
}
和
template <typename DataType, class KeyType>
bool BSTree<DataType, KeyType>::BSTreeNode::operator>(const BSTreeNode*& other)
{
if((*other).dataItem < (*this).dataItem)
{
return true;
}
return false;
}
答案 0 :(得分:0)
我假设您打算添加一个 - &gt;在* ptr之后而不是&gt;之后
if((*ptr)>dataItem > newDataItem)
虽然它仍然是不正确的。几点建议:
仍然,从错误看起来你需要重载&lt;和&gt;您的数据类型的运算符。你能用实际的通话代码更新你的帖子吗?
答案 1 :(得分:0)
例如,请查看Compare template parameter passed to std::map。
您的模板应调用其比较功能。
它的默认Compare方法应该是std :: less。
如果类型定义operator <
,则类型支持std :: less;如果它不想这样做,那么它可以将非默认比较函数作为模板参数传递给你的模板。
您也不需要定义operator >
,因为您可以编写模板代码来测试if (b < a)
而不是if (a < b)
。
答案 2 :(得分:0)
你需要定义以下重载(注意,这是你需要做的,这还没有完成):
class BSTreeNode // Inner class: facilitator for the BSTree class
{
public:
// Constructor
BSTreeNode ( const DataType &nodeDataItem, BSTreeNode *leftPtr, BSTreeNode *rightPtr );
// New overloads
inline bool operator< (const X& lhs, const X& rhs){ /* do actual comparison */ }
inline bool operator> (const X& lhs, const X& rhs){return operator< (rhs,lhs);}
// Data members
DataType dataItem; // Binary search tree data item
BSTreeNode *left, // Pointer to the left child
*right; // Pointer to the right child
};
您尚未完成
您需要向BSTree添加功能以扩展此节点重载
// Binary search tree manipulation operations
void insert ( const DataType& newDataItem ); // Insert data item
bool retrieve ( const KeyType& searchKey, DataType& searchDataItem ) const;
inline bool operator< (const X& lhs, const X& rhs){ return this->dataItem->operator<(lhs,rhs); }
inline bool operator> (const X& lhs, const X& rhs){ return this->dataItem->operator>(lhs,rhs); }
我们可以将其全局定义为命名空间的一部分
namespace MyBSTree
{
inline bool operator< (const X& lhs, const X& rhs){ return this->dataItem->operator<(lhs,rhs); }
inline bool operator> (const X& lhs, const X& rhs){ return this->dataItem->operator>(lhs,rhs); }
}
您可以在比较中提取最后一个值,而不是使用节点对象。深入创建一个内部值的get,这种方式的比较将是基本数据类型而不是Object。
答案 3 :(得分:0)
我有同样的书。我发现因为我们得到了#34;容器&#34;通过DataType参数的对象类型,我可以实例化一个持有DataType项并调用.getKey()函数。它运作良好。这可能超过了截止日期,但这个想法对书中的其他结构有很大帮助。这是我的意思。
template<typename DataType, typename KeyType>
void BSTree<DataType,KeyType>::insert ( const DataType& newDataItem )
{
DataType hold = newDataItem;
KeyType holdKey = newDataItem.getKey(); //All our parameters must have getKey() return int
insertHelper( root, holdKey, newDataItem ); // or however yours went
}
这允许您通过创建虚拟持有者并调用虚拟的.getKey()来比较键值。
编辑:抱歉,将错误的收件人数据类型作为getKey返回,但你应该明白这一点。字符串有一个内置的比较运算符,因此您不必为每个类/结构重写它。