二叉搜索树
Binary Search Tree
我现在正在做一个学校的项目。任务是在给定相应的头文件的情况下编写模板化二叉搜索树的实现。
我的问题是,因为它是模板化的,我不确定如何在插入或查找数据项之间进行比较。
头文件:
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:School302Labs7BSTree.cpp no match for 'operator>' in 'ptr->BSTree<TestData, int>::BSTreeNode::dataItem > newDataItem'
49 E:School302Labs7BSTree.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;
}
我假设您的意思是在*ptr之后添加->而不是在
之后添加>if((*ptr)>dataItem > newDataItem)
,尽管它仍然是不正确的。几个建议:
- 您没有处理数据项相等的情况。一个简单的解决方法就是用else替换else-if。
- (* ptr)。dataItem应替换为ptr->dataItem
仍然,从错误中看起来你需要重载<和>操作符的数据类型。你能把实际的电话号码更新一下你的帖子吗?和>
例如,查看传递给std::map的Compare模板形参。
你的模板应该调用它的Compare函数
它的默认比较方法应该是std::less。
如果一个类型定义了operator <
,则它支持std::less;如果它不想这样做,那么它可以将一个非默认的比较函数作为模板参数传递给你的模板。
您也不需要定义operator >
,因为您可以编写模板代码来测试if (b < a)
而不是if (a < b)
。
您需要定义以下重载(注意,这是您需要做的,这还没有完成):
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
};
您还没有完成
你需要添加功能到你的btree来扩展这个Node重载
// 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,这样比较的是基本数据类型,而不是对象。
我也有这本书。我发现,因为我们通过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返回,但你应该得到的想法。字符串有一个内置的比较操作符,因此您不必为每个类/结构重写它。
- 有根的二进制搜索树.保留与其父级的链接
- 正在尝试重载二进制搜索树分配运算符
- 使用C++创建特殊的二叉搜索树
- 在递归二叉搜索树中搜索
- 在二叉搜索树中插入时出现分段错误
- C++二叉搜索树模板从函数返回节点
- 我可以在没有堆栈的情况下在二叉搜索树中实现迭代器吗?
- 在二叉搜索树C++中计算平均值
- 在字符串的二叉搜索树中搜索子字符串 - C++
- 在二叉搜索树中插入新元素
- 如何打印在二叉搜索树中找到的数据?
- 查找存储在二叉搜索树的所有非叶子中的数据总和?(返回整数的独立递归函数
- 这是一个二叉搜索树吗?黑客排名问题
- 二叉搜索树 - 实现"search"函数
- 二叉搜索树的 C++ 实现中的EXC_BAD_ACCESS错误
- 删除二叉搜索树 (C++) 中的单个元素
- 将值存储在带有C++的二叉搜索树中
- 二叉搜索树未将插入值加载到树中
- 二叉搜索树使用最常用的节点来打印出某些语句
- 如何以特定格式C++打印二叉搜索树