- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在编写一个增强二叉搜索树类。我用整数完成了简单版本,现在我想用模板实现相同的结构。我遇到的问题如下。
我需要一棵树,里面装满了我无法更改的库中的对象。这些对象没有我当前用于我的树实现的 greater 运算符。我该怎么做?
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;
}
}
现在,正如我之前提到的,如果 key 是具有更大运算符(如 int)的东西,则此方法有效。我如何编写代码来处理没有此运算符的对象?
例如如果我需要用一个代表点的类来填充树,而这个类不支持更大的运算符。假设我想基于 x 轴存储它们,因此如果 x1>x2,则点 p1(x1,y1) 大于点 p2(x2,y2)。我可以为类似的东西编写函数,但我不知道如何在树中传递这个函数以及如何保持像 int 这样的对象的默认比较。
提前致谢
最佳答案
你可以看看STL对关联容器做了什么,这个问题已经解决了。
取std::set
例如(本质上是二叉搜索树),有<
的比较函数作为 comparator
嵌入到树的类型中.你可以拥有:
// The comparison object
struct Comp
{
bool operator()(int i1, int i2)
{
return i1 < i2;
}
};
// using the comparison object as the comparator
std::set<int, Comp> lala;
同样,你可以让你的树布局看起来像那样
template <typename keytype, typename Comp>
struct Node
{
....
friend bool operator<(Node const& left, Node const &right)
{ // Now your nodes know how to compare themselves
return Comp(left, right);
}
....
};
template <typename item, typename Comp>
class Tree
{
....
Node<item, Comp> *root;
....
};
现在,在为您的 Tree
编写代码时您可以编写的成员函数
n1 < n2 ; // node1 < node2
并且知道它们是根据您指定为模板参数的比较器进行比较的
作为奖励功能,您可以查看 here一种在您定义了<
后为您生成所有关系运算符 的方法operator (实际上比较器的定义是这个设计强制要求的,所以 Node
继承自 relational
会自动给你 >
, >=
, <=
, ==
, !=
生成)
template <typename keytype, typename Comp>
struct Node : relational<Node<keytype,Comp>>
{ ... }
关于c++ - 将运算符重载作为模板参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24020655/
Or 运算符 对两个表达式进行逻辑“或”运算。 result = expression1 Or expression2 参数 result 任意数值变量。 expression1 任意
Not 运算符 对表达式执行逻辑非运算。 result = Not expression 参数 result 任意数值变量。 expression 任意表达式。 说明 下表显示如何
Is 运算符 比较两个对象引用变量。 result = object1 Is object2 参数 result 任意数值变量。 object1 任意对象名。 object2 任意
\ 运算符 两个数相除并返回以整数形式表示的结果。 result = number1\number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
And 运算符 对两个表达式进行逻辑“与”运算。 result = expression1 And expression2 参数 result 任意数值变量。 expression1
运算符(+) 计算两个数之和。 result = expression1 + expression2 参数 result 任意数值变量。 expression1 任意表达式。 exp
我对此感到困惑snippet : var n1 = 5-"4"; var n2 = 5+"4"; alert(n1); alert(n2); 我知道 n1 是 1。那是因为减号运算符会将字符串“4”转
我想我会得到 12,而不是 7。 w++,那么w就是4,也就是100,而w++, w 将是 8,1000;所以 w++|z++ 将是 100|1000 = 1100 将是 12。 我怎么了? int
Xor 运算符 对两个表达式进行逻辑“异或”运算。 result = expression1 Xor expression2 参数 result 任意数值变量。 expression1
Mod 运算符 两个数值相除并返回其余数。 result = number1 Mod number2 参数 result 任意数值变量。 number1 任意数值表达式。 numbe
Imp 运算符 对两个表达式进行逻辑蕴涵运算。 result = expression1 Imp expression2 参数 result 任意数值变量。 expression1 任
Eqv 运算符 执行两个表达式的逻辑等价运算。 result = expression1 Eqv expression2 参数 result 任意数值变量。 expression1 任
我有一个运算符重载的简单数学 vector 类。我想为我的运算符(operator)获取一些计时结果。我可以通过计时以下代码轻松计时我的 +=、-=、*= 和/=: Vector sum; for(s
我是用户定义比较运算符的新手。我正在读一本书,其中提到了以下示例: struct P { int x, y; bool operator、运算符<等),我们
在 SQL 的维基百科页面上,有一些关于 SQL 中 bool 逻辑的真值表。 [1] 维基百科页面似乎来源于 SQL:2003 标准。 等号运算符 (=) 的真值表与 SQL:2003 草案中的 I
我遇到了一个奇怪的 C++ 运算符。 http://www.terralib.org/html/v410/classoracle_1_1occi_1_1_number.html#a0f2780081f
我正在阅读关于 SO 和 answers 中的一个问题,它被提到为: If no unambiguous matching deallocation function can be found, pr
我偶然发现了这个解决方案,但我无法理解其中到底发生了什么。谁能解释一下! 据我了解,它试图通过计算一半的单元格然后将其加倍来计算 a*b 网格中的单元格数量。但是我无法理解递归调用。 请不要建议其他解
Go的基本类型 布尔类型bool 长度:1字节 取值:布尔类型的取值只能是true或者false,不能用数字来表示 整型 通用整型 int / uint(有符号 / 无符号,下面也类似) 长度:根据运
在本教程中,您将学习JavaScript中可用的不同运算符,以及在示例的帮助下如何使用它们。 什么是运算符? 在JavaScript中,运算符是一种特殊符号,用于对运算数(值和变量)执行操作。例如,
我是一名优秀的程序员,十分优秀!