AVL树C 的Ostream操作员
Ostream Operator for AVL Trees C++
议程是使用Ostream Operator打印AVL树的内容。内容必须以特定格式打印。
使用模板实现树。一个简单的主要实现。
AVLTree<int, float> tree;
for(int i = 0; i < 10; i++)
tree.insert(i, i+0.1);
cout << tree;
Ostream Operator
friend ostream& operator<<(ostream& out, const AVLTree& v)
{
out << "{";
v.print(out, v.root);
out << "}";
return out;
}
void print(AVLnode<KEY,INFO>* curr)const
{
if(curr)
{
print(curr->left);
print(curr->right);
}
}
void print(ostream& out, AVLnode<KEY, INFO>* curr)const
{
if(curr)
{
print(out, curr->left);
out << curr->Key_ << ": " << curr->Info_<<", ";
print(out, curr->right);
}
}
我有两个用于打印的助手功能。
我得到的输出是
{1:1.1, 2:2.1. 3:3.1, 4:4.1, 5:5.1, 6:6.1, 7:7.1, 8:8.1, 9:9.1, }
所需的输出为
{1:1.1, 2:2.1. 3:3.1, 4:4.1, 5:5.1, 6:6.1, 7:7.1, 8:8.1, 9:9.1}
"不应该打印,如何检测树的最后一个元素?我不了解情况。这很简单,但我看不到它。
考虑此问题的另一种方法是打印逗号 first ,而不是最后。这样,您将永远不会得到尾随的逗号,因为它将是第一个打印的物品。
可以通过在辅助功能中引入bool
参考变量来完成(未测试):
friend ostream& operator<<(ostream& out, const AVLTree& v)
{
bool firstTime = true;
out << "{";
v.print(out, v.root, firstTime);
out << "}";
return out;
}
void print(ostream& out, AVLnode<KEY, INFO>* curr, bool& firstTime) const
{
if (curr)
{
print(out, curr->left, firstTime);
out << (firstTime?"":", ") << curr->Key_ << ": " << curr->Info_;
firstTime = false;
print(out, curr->right, firstTime);
}
}
firstTime
跟踪是否是第一次打印。如果是这种情况,则不会打印逗号,否则打印了逗号。
我可以看到的两种方法:
1。
生成字符串,存储在变量中,然后删除最后2或3个字符(取决于间距),然后附加}
以关闭格式,然后输出到ostream
。
2。
输入第一个打印功能时,将计数器设置为0,然后每次处理节点时增加。这将为您提供打印的物品总数。然后,您可以将其与AVL树中的项目总数进行比较。您还必须跟踪某处的总数。
我将使用选项ONE,因为现在更容易实现。另外,AVL树不应该知道其中有多少个物品。同样,您的树越大,打印速度越慢,因为语句和count
增量会增加更多。这两个操作很少,但是如果您收到数千或数百万的项目,则会加起来。
引入一个简单的if语句条件:
out << curr->Key_ << ": " << curr->Info_;
if (some_condition_of_yours) {
out << ", ";
}
else {
out << " ";
}
用内部逻辑替换条件
我想您需要print()
中的其他参数才能知道右边是否有东西。
示例(注意:未测试)
friend ostream& operator<<(ostream& out, const AVLTree& v)
{
out << "{";
v.print(out, v.root, false);
out << "}";
return out;
}
void print (ostream & out, AVLnode<KEY, INFO> * curr, bool proComma) const
{
if (curr)
{
bool proC2 = proComma || (NULL != curr->right);
print(out, curr->left, proC2);
out << curr->Key_ << ": " << curr->Info_;
if ( proC2 )
out << ", ";
print(out, proComma);
}
}
所以一段时间后,我弄清楚了问题是什么,并且能够提出一个简单的解决方案,所以我决定在忘记这样做之前发布答案。
真的很难检测到树上的最后一个节点,因为树的左侧和右侧都有无效的结尾。因此,打印整棵树并删除额外的字符确实做得很好。
template<typename KEY, typename INFO>
void AVLTree<KEY, INFO>:: print(ostream& out, AVLnode<KEY,INFO>* curr) const{
//sstream operator to calc the output and delete (n-1) of the output.
out << "{";
std::stringstream ss;
printHelp(ss, curr);
std::string output = ss.str();
if (output.length() > 1)
output.erase(output.end()-2, output.end());
out << output;
out << "}";
}
template<typename KEY, typename INFO>
void AVLTree<KEY, INFO>::printHelp(std::stringstream& ss, AVLnode<KEY, INFO>* curr) const{
if(curr){
printHelp(ss, curr->left);
ss << curr->Key_<< ": " << curr->Info_ << ", ";
printHelp(ss, curr->right);
}
}
,然后使用root节点作为参数和Ostream对象的Ostream Operator。
friend ostream& operator<<(ostream& out, const AVLTree& v){
v.print(out, v.root);
return out;
}
还有另一种选择,将它们推入堆栈并弹出最后一个字符并完全打印堆栈,这非常接近我所需的内容,但由于树上有接近15,000个节点,因此非常效率。/p>
- ostream过载时的缓冲区冲洗
- 需要从 istream 和 ostream 派生 iostream
- <<操作员在下面的行中工作
- "ostream &os"有什么用?
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- C++ 与操作员不匹配<<
- 操作员C++的模棱两可的过载
- C++中>>操作员过载时出现问题?
- NaN 上的宇宙飞船操作员
- 我的运算符重载是否有效<<(流插入)左操作数不是 ostream
- C++表达SFINAE和ostream操纵器
- 比根<操作员
- SFINAE不能防止模棱两可的操作员过载吗?
- 什么是现实中的"endl"(或任何输出操纵器)?它是如何实现的,它如何与操作员<<一起工
- 在抛出 'std::runtime_error' 的实例后终止调用 what(): Filebuf 和 ostream 的 I/O 错误
- AVL树C 的Ostream操作员
- 为什么"ostream & os"必须在那里C++操作员过载?
- Ostream操作员Strangley不接受我的堆栈指针
- 在C++重载cout ostream操作员
- ostream << 具有模板类的操作员,无法访问私有成员