【发布时间】:2014-07-24 02:42:28
【问题描述】:
我正在编写一个增强的二叉搜索树类。我用整数完成了简单的版本,现在我想用模板实现相同的结构。我遇到的问题如下。
我需要有一棵树,里面装满了我无法更改的库中的对象。这些对象没有我当前用于树实现的更大运算符。我该怎么做?
Tree.h 文件有一个结构节点,其中包含节点或叶子的所有信息以及实际的树代码
结构节点
template <typename keytype>
class
template <typename keytype >
struct Node {
//key value
keytype key;
//node type , leaf ot internal Node
bool leaf;
//childern pointers
struct Node<keytype>* left;
struct Node<keytype>* right;
//height of tree
int height;
//ansestor
struct Node<keytype>* ansestor;
};
template <typename item>
class Tree{
public:
Tree(); //tree constructor
void insert(item key); //inserts a new element
bool remove(item key); //remove an existing element
void printInOrder(); //print tree in order
int getHeight(); //returns the height of the tree
Node<item> getFirst(); //returns the first element of tree-list
Node<item> getLast(); //returns the last element of tree-list
Node<item> getNext(); //returns the next value of the last accessed element
Node<item> getPrevious(); //returns the privious value of the last accessed element
private:
int height,
numOfElements;
Node<item>* root;
Node<item>* listPosition; //internal pointer, points to an element in the list
/***************************private functions**********************/
void _insert(Node<item> *&newNode, item &key); //private insertion function
bool _remove(Node<item> *¤tNode,item &key); //remove the leaf with key is it exists
void _balanceTree(Node<item> *¤tNode); //balance the tree if needed
void _rotateLeft(Node<item> *&root); //performs a left rotation
void _rotateRight(Node<item> *&root); //performs a right rotation
Node<item>* _createNewNode(const item &key, //alocates memeory space for new leaf/node
const bool &leaf=true, //and passes it defaults or given values
Node<item>* left=NULL, Node<item>* right=NULL,
const int &height=0, Node<item>* ansestor=NULL);
void _updateHeight(Node<item> *¤tNode); //updates the height of a node
void _inOrderTraversal(Node<item>* currentNode); //print in order function
void _printNodesInfo(Node<item>* currentNode); //print node function
bool _removeLeft(Node<item> *&parent); //removes the left child of a internal node
bool _removeRight(Node<item> *&parent); //removes the right chold of a internal node
Node<item> _getFirst(Node<item> *root); //returns the value of the first item and
//sets the internal pointer to that element
Node<item> _getLast(Node<item> *root); //returns the value of the last item and
//sets the internal pointer to that element
Node<item>* _next(Node<item> *leaf); //returns a pointer to leaf's next element and
//sets the internal pointer to that element
Node<item>* _previous(Node<item> *leaf); //returns a poiunter to leaf's previous element and
//sets the internal pointer to that element
};
当我想做插入等来查找节点的位置时,我使用以下代码比较键
if (key>currentNode->key)
{
if (DEBUG){
cout<<">>>>>>>>>>>>>>go right>>>>>>>>>"<<endl;
}
this->_insert(currentNode->right,key);
}
else
{
if (DEBUG){
cout<<"<<<<<<<<<<<<<go left<<<<<<<<<<<"<<endl;
}
this->_insert(currentNode->left,key);
}
这是函数_insert的一部分
template <typename item>
void Tree<item>::_insert(Node<item> *¤tNode, item &key){
if (this->root==NULL)
{/*the tree is empty at this point*/
if (DEBUG){
cout<<"tree was empty"<<endl;
}
/*inititialize the root*/
root= this->_createNewNode(key,true);
this->numOfElements=1;
return;
}
else if (currentNode->height==0)//currentNode->leaf==true
{//we reached a leaf
if (DEBUG){
cout<<"-------insertion found-----"<<endl;
}
Node<item>* oldLeaf= currentNode; //keep the pointer to the old leaf
Node<item>* privious;
currentNode= this->_createNewNode(654, false); //create a new internal node and link it to the tree
currentNode->height=1; //set its height to 1
Node<item>* newLeaf = _createNewNode(key, true);
if (newLeaf->key>oldLeaf->key)
{/*the new leaf is the biggest element in the tree*/
currentNode->right= newLeaf;
currentNode->left= oldLeaf;
//list connection
}
else
{/*normal insertion*/
currentNode->right= oldLeaf;
currentNode->left= newLeaf;
//list connection
privious=this->_previous(oldLeaf);
if (privious!=NULL){//old element was not the first one
privious->right=newLeaf;
newLeaf->left=privious;
}
}
currentNode->left->right=currentNode->right;
currentNode->right->left=currentNode->left;
currentNode->key= currentNode->left->key;
currentNode->left->ansestor= currentNode;
this->numOfElements++;
return;
}
else
{/*search deeper to the tree*/
if (key>currentNode->key)
{
if (DEBUG){
cout<<">>>>>>>>>>>>>>go right>>>>>>>>>"<<endl;
}
this->_insert(currentNode->right,key);
}
else
{
if (DEBUG){
cout<<"<<<<<<<<<<<<<go left<<<<<<<<<<<"<<endl;
}
this->_insert(currentNode->left,key);
}
//this balance tree
this->_updateHeight(currentNode);
this->_balanceTree(currentNode); //balance the tree if needed
this->_updateHeight(currentNode);
//cout <<"-----------------test height is "<<currentNode->height<<endl;
return;
}
}
现在正如我之前提到的,如果键是具有更大运算符的东西(如 int),则此方法有效。我如何编写代码来处理没有此运算符的对象?
例如如果我需要用代表点的类填充树并且此类不支持更大的运算符。假设我想基于 x 轴存储它们,因此如果 x1>x2 点 p1(x1,y1) 大于点 p2(x2,y2)。我可以为类似的东西编写函数,但我不知道如何在树中传递这个函数以及如何为 int 等对象保留默认比较。
提前致谢
【问题讨论】:
-
我相信您缺少
class的定义(而不是struct)。还有那个函数体在哪里?this是什么?currentNode是什么?
标签: c++ class templates operator-overloading