简体   繁体   English

用于AVL树C ++的Ostream运算符

[英]Ostream Operator for AVL Trees C++

The agenda is to print the contents of an AVL Tree using the ostream operator. 议程是使用ostream运算符打印AVL树的内容。 The contents have to be printed in a specific format. 内容必须以特定格式打印。

The Tree is implemented using templates. 该树是使用模板实现的。 A simple main implementation. 一个简单的主要实现。

AVLTree<int, float> tree;
for(int i = 0; i < 10; i++)
   tree.insert(i, i+0.1);
cout << tree;

Ostream Operator Ostream运算符

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);
        }
    }

I have two helper functions for printing. 我有两个打印辅助功能。

The output I get is 我得到的输出是

{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, }

The required output is 所需的输出是

{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}

The "," is not supposed to be printed, how to you detect the last element of the tree? 不应打印“,”,如何检测树的最后一个元素? I fail to understand the condition. 我不了解情况。 It is simple but I fail to see it. 很简单,但我看不到。

Introduce a simple if statement condition: 介绍一个简单的if语句条件:

out << curr->Key_ << ": " << curr->Info_;
if (some_condition_of_yours) {
    out << ", ";
} 
else {
    out << " ";
}

Replace the condition with your internal logic. 用内部逻辑替换条件

Two ways I can see to accomplish this: 我可以通过两种方式实现这一目标:

1. 1。

Generate the string, store in variable, then drop the last 2 or 3 characters (depending on spacing), then append the } to close the format, then output to ostream . 生成字符串,存储在变量中,然后删除最后2或3个字符(取决于间距),然后附加}以关闭格式,然后输出到ostream

2. 2。

When entering the first print function, set a counter to 0, and increment every time handle a node. 进入第一个打印功能时,将计数器设置为0,并在每次处理节点时递增。 This will give you a total number of items printed. 这将为您提供打印的项目总数。 You can then compare that to the total number of items in the AVL tree. 然后,您可以将其与AVL树中的项目总数进行比较。 You'll have to keep track of the total number of items somewhere as well. 您还必须跟踪某处的项目总数。

I would use option one, because it is easier to implement now. 我将使用选项一,因为现在更容易实现。 Also, AVL trees shouldn't be in charge of knowing how many items are in them. 同样,AVL树不应该负责知道其中有多少个项目。 Also also, the larger your tree is, the slower printing will be, because there will be more if statements and count increments. 同样,树越大,打印速度就越慢,因为if语句和count增量会更多。 Those two operations are minimal, but if you get thousands or millions of items, it'll add up. 这两个操作是最少的,但是如果您获得数千或数百万个项目,它将累加起来。

I suppose you need an additional parameter in print() to know if there is something on the right. 我想您需要在print()附加一个参数来知道右边是否有东西。

By example (caution: not tested) 通过示例(警告:未经测试)

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);
        }
    }

Another way to think about this problem is to print the comma first , not last. 思考这个问题的另一种方式是打印逗号,不会持续太久。 This way you will never get a trailing comma, since it will be the first item printed. 这样,您将永远不会看到逗号,因为它将是第一个打印的项目。

That can be accomplished by introducing a bool reference variable in the helper functions (not tested): 这可以通过在辅助函数(未测试)中引入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);
    }
}

The firstTime tracks whether it is the first time being printed. firstTime跟踪是否是第一次打印。 If this is the case, then no comma is printed, otherwise a comma is printed. 如果是这种情况,则不打印逗号,否则打印逗号。

So after a while I figured out what the issue was and was able to come up with a simple solution, so I decided to post an answer before I forget to do so. 因此,过了一会儿,我弄清了问题所在,并提出了一个简单的解决方案,因此,我决定在忘记之前发布答案。

It is really hard to detect the last node in the tree since both the left and right sides of the trees have a NULL ending. 实际上很难检测树中的最后一个节点,因为树的左侧和右侧都以NULL结尾。 So printing out the whole tree and deleting the extra characters did the trick quite well. 因此,打印出整棵树并删除多余的字符就可以了。

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);
        }
}

and then the ostream operator which uses the print function with the root node as a parameter and the ostream object. 然后是oprint运算符,该运算符使用带有根节点作为参数和ostream对象的print函数。

friend ostream& operator<<(ostream& out, const AVLTree& v){
        v.print(out, v.root);
        return out;
    }

There was also another option of pushing them into a stack and poping the last characters and printing the stack entirely, this was very close to what I needed but would be very inefficient as the tree had close to 15,000 nodes on it. 还有另一种选择将它们推入堆栈并弹出最后一个字符并完全打印堆栈,这与我需要的非常接近,但是效率很低,因为树上有将近15,000个节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM