-1

I've always wanted to make a binary tree, so here I am experimenting, and I've bumped into a wall, more specificly , outputting the binary tree with the operator <<.Currently what it does is, printing the reference of that value I assume, and if I try to change obj to *obj,I get errors.(I know that this way ,the current program will output only the root value).

Bonus question :how to make the writeStuff() function output the whole tree correctly ?

My code:

#include <iostream>
#include <vector>

class binFa
{
    char value;
    binFa *righElem;
    binFa *leftElem;

  public:
    binFa(char elem) : value(elem)
    {
        rightElem = NULL;
        leftElem = NULL;
    }
    binFa(const binFa &fa)
    {
        value = fa.value;
        rightElem = new binFa(fa.rightElem->value);
        leftElem = new binFa(fa.leftElem->value);
    }
    binFa &operator<<(char elem)
    {
        if (elem == '0')
            leftElem = new binFa(elem);
        else
            rightElem = new binFa(elem);
        return *this;
    }
    void writeStuff(binFa *fa)
    {
        std::cout << fa->value << " ";
        if (fa->rightElem != NULL || fa->leftElem != NULL)
        {
            writeStuff(fa->leftElem);
            writeStuff(fa->rightElem);
        }
    }
    std::ostream &operator<<(std::ostream &os)
    {
        os << this->value;
        return os;
    }
};

int main()
{
    binFa *obj = new binFa('/');
    *obj << '0' << '1' << '0';
    std::cout << obj;
    obj->writeStuff(obj);
    delete obj;
    return 0;
}
Gameerik
  • 5
  • 4
  • 1
    `righElem` -> `rightElem`? – user4581301 May 24 '18 at 17:44
  • `obj->writeStuff(obj);` looks a wee bit odd. Why pass yourself into yourself? – user4581301 May 24 '18 at 17:46
  • Well it is only a prototype, what I really want to do is create a **writeStuff()** function which takes no parameters, call **this** and the other **writeStuff(binFa *fa)** to have a nice recursive function :) – Gameerik May 24 '18 at 17:48
  • 1
    `std::ostream &operator<<(std::ostream &os)` does not work as a member variable. More on that at [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading). This is your bug, by the way. You don't have a proper overload for `<<` so the compiler is making a guess. – user4581301 May 24 '18 at 17:48
  • 1
    Oh smurf, no. I'm wrong. You told it to print a pointer. It printed a pointer. You have two bugs. Try it without dynamically allocating `binFa`: `binFa obj('/');` You'll get a massive crawl of error messages telling you `operator<<` is wrong. – user4581301 May 24 '18 at 17:51
  • I get a "no match for operator<<" error – Gameerik May 24 '18 at 17:55
  • *how to make the `writeStuff()` function output the whole tree correctly ?* So you basically want us to do your Homework, right? First try to build it, before you print it: https://en.wikipedia.org/wiki/Binary_search_tree – JeJo May 24 '18 at 17:56
  • @JeJo no, this is not a homework, I am just experimenting, and my function currently is probably limited only to the "root" value and it's 2 child's, I think I even screwed up the way I did put them in the tree, since I am overwriting the Childs. That question is almost irrelevant, what I have really trouble with , is the main question. – Gameerik May 24 '18 at 17:59

1 Answers1

1

Problem 1

binFa *righElem;

A silly typo.

binFa *rightElem;

Looks about right.

Problem 2

std::cout << obj;

obj is a pointer, so of course it prints out an address. Don't use a pointer. There is no need for dynamic allocation here.

int main()
{
    binFa obj('/');
    obj << '0' << '1' << '0';
    std::cout << obj;
//    obj.writeStuff(&obj); ignoring. One question at a time, please
    return 0;
}

Problem 3

std::ostream &operator<<(std::ostream &os)

is not a valid stream operator. Covered well by What are the basic rules and idioms for operator overloading? so there's no point repeating it

Problem 4

One would expect std::cout << obj; to print out the entire tree, so

friend std::ostream &operator<<(std::ostream &os,
                                const binFa & bin)
{
    os << bin.value;
    return os;
}

probably won't cut it. What kind of traversal do you want? Perform some research on Tree Traversal algorithms. A simple approach:

friend std::ostream &operator<<(std::ostream &os,
                                const binFa & bin)
{
    os << bin.value;
    if (bin.rightElem)
    {
        os << *bin.rightElem;
    }
    if (bin.leftElem)
    {
        os << *bin.leftElem;
    }
    return os;
}

but you need to figure out which traversal is right for you. Warning: The above is recursive and can overrun the stack for a large tree.

user4581301
  • 33,082
  • 7
  • 33
  • 54