-1

Hey guys just having some issues with getting print out for parent and siblings of each node in the tree. Here is the full block of code

/*
---------------
Binary sort tree
*/

#include <iostream>
#include <cstdlib>
#include <cstdint>
using namespace std;

class BinSearchT
{
    private:
        struct tr_node
        {
           tr_node* left;
           tr_node* right;
           tr_node* parent;
           int data;
        };
        tr_node* root;
    public:
        BinSearchT()
        {
           root = NULL;
        }
        bool isEmpty() const { return root==NULL; }
        void pInorder();
        void inorder(tr_node*);
        void insert(int);
        void remove(int);
};


void BinSearchT::insert(int d)
{
    tr_node* t = new tr_node;
    //tr_node* parent;
    t->data = d;
    t->left = NULL;
    t->right = NULL;
    t->parent = NULL;
  // is this a new tree?
  if(isEmpty()) root = t;
  else
  {
    //Note: ALL insertions are as leaf nodes
    tr_node* curr;
    curr = root;
    // Find the Node's parent
    while(curr)
    {
        t->parent = curr;
        if(t->data > curr->data) curr = curr->right;
        else curr = curr->left;
    }

    if(t->data < t->parent->data)
       t->parent->left = t;
    else
       t->parent->right = t;
  }
}



void BinSearchT::pInorder()
{
  inorder(root);
}

void BinSearchT::inorder(tr_node* p)
{
    if(p != NULL)
    {
        if(p->left) inorder(p->left);
        //int left=*reinterpret_cast<int *>(p->left);
        //int right=*reinterpret_cast<int *>(p->right);
        //int parent=*reinterpret_cast<int *>(p->parent);
        cout<<"\n "<<p->data<<" Left: "<<p->left->data<<" Right: "<<p->right->data<<" Parent: "<<p->parent->data<<endl;


        if(p->right) inorder(p->right);
    }
    else return;
}

int main()
{
    BinSearchT b;
    int ch,tmp,tmp1;
    while(1)
    {
       cout<<endl<<endl;
       cout<<" BinSearchTOps "<<endl;
       cout<<" ----------------------------- "<<endl;
       cout<<" 1. Insertion/Creation "<<endl;
       cout<<" 2. In-Order Traversal "<<endl;
       cout<<" 3. Exit "<<endl;
       cout<<" Enter your choice : ";
       cin>>ch;
       switch(ch)
       {
           case 1 : cout<<" Enter Number to be inserted(just one) : ";
                    cin>>tmp;
                    b.insert(tmp);
                    break;
           case 2 : cout<<endl;
                    cout<<" In-Order Traversal "<<endl;
                    cout<<" -------------------"<<endl;
                    b.pInorder();
                    break;
           case 3 : system("pause");
                    return 0;
                    break;
       }
    }
}

so the issue that i am having is that the parent and the siblings are printing out as memory locations and if the value is supposed to be null it prints out all 0's which makes me think that it is working and that i just need to find out how to get those memory locations.

Now i do some searching and found this post on stackoverflow C++ - Get value of a particular memory address

this is what i've tried

//int left=*reinterpret_cast<int *>(p->left);
//int right=*reinterpret_cast<int *>(p->right);
//int parent=*reinterpret_cast<int *>(p->parent);

i commented that part out of the program since it did not work. I would appreciate any help i can get. input: 10 20 8 4 5 15 17 2 I cant post images so i cant post the output.

EDIT: OUTPUT

2  Left: 00000000 Right:00000000 Parent:00484C58
4  Left: 00484F98 Right:00484CA8 Parent:00484C08
5  Left: 00000000 Right:00000000 Parent:00484C58
8  Left: 00484C58 Right:00000000 Parent:00484BB8
10 Left: 00484C08 Right:00484EF8 Parent:00000000
15 Left: 00000000 Right:00484F48 Parent:00484BB8
17 Left: 00000000 Right:00000000 Parent:008A4F48
20 Left: 008A4F48 Right:00000000 Parent:008A4BB8

But it should be

2  Left: Null     Right:Null     Parent:4
4  Left: 2        Right:5        Parent:8
5  Left: Null     Right:Null     Parent:4
8  Left: 4        Right:Null     Parent:10
10 Left: 8        Right:20       Parent:Null    
15 Left: Null     Right:17       Parent:20
17 Left: Null     Right:Null     Parent:15
20 Left: 15       Right:Null     Parent:10

As you can see where ever the numbers match the memory locations also match which supports the fact that it is working just need to get the numbers and not the memory address.

Community
  • 1
  • 1
  • Why would you not just read `p->data` after you just wrote the int to that location? What is `reinterpret_cast(p->left)` supposed to do? – danielschemmel Apr 29 '14 at 16:51
  • From what i understand from what is written here -> http://stackoverflow.com/questions/12298208/c-get-value-of-a-particular-memory-address it is suppose to deference the memory address. – user3348907 Apr 29 '14 at 16:55
  • What does the first line after your commented out code print out? – Mdev Apr 29 '14 at 16:57

2 Answers2

1

Add #include <iomanip> at the top of your file to format your output as I do in this answer:

You're just not checking whether or not the pointer is valid. If the pointer to the child node is NULL then you can't access the data attribute there, because no memory has been allocated for it yet.

Also, remember if you ever are finding yourself needing to access a raw address in memory instead of using a simple pointer, you're most likely doing something wrong/doing it the hard way.

Simply do a check to see if the children/parent nodes are null or not.

setw(4) and left sets the width to 4 and formats the output to be left-aligned.

#include <iomanip>

...

void BinSearchT::inorder(tr_node* p)
{
    if(p != NULL)
    {
        if(p->left) inorder(p->left);

        if (p->left)
            cout << "Left: " << setw(4) << left << p->left->data << "\t";
        else
            cout << "Left: Null\t";

        if (p->right)
            cout << "Right: " << setw(4) << left << p->right->data << "\t";
        else
            cout << "Right: Null\t";

        if (p->parent)
            cout << "Parent: " << setw(4) << left << p->parent->data << endl;
        else
            cout << "Parent: Null" << endl;

        if(p->right) inorder(p->right);
    }
    else 
        return;
}

After the insertions:

 BinSearchTOps 
 ----------------------------- 
 1. Insertion/Creation 
 2. In-Order Traversal 
 3. Exit 
 Enter your choice : 2

 In-Order Traversal 
 -------------------
Left: Null  Right: Null Parent: 4   
Left: 2     Right: 5    Parent: 8   
Left: Null  Right: Null Parent: 4   
Left: 4     Right: Null Parent: 10  
Left: 8     Right: 20   Parent: Null
Left: Null  Right: 17   Parent: 20  
Left: Null  Right: Null Parent: 15  
Left: 15    Right: Null Parent: 10  
Mdev
  • 2,440
  • 2
  • 17
  • 25
  • Thanks, was able to speak to my professor and she pointed out the same thing that i was not checking for Null as well as the ->data that i was missing. I appreciate the help. – user3348907 Apr 29 '14 at 18:26
0

you clearly have a problem at this part of code :

if(p->left) inorder(p->left);
        //int left=*reinterpret_cast<int *>(p->left);
        //int right=*reinterpret_cast<int *>(p->right);
        //int parent=*reinterpret_cast<int *>(p->parent);
        cout<<"\n "<<p->data<<" Left: "<<p->left->data<<" Right: "<<p->right->data<<" Parent: "<<p->parent->data<<endl;

If p->left is null your code will give a seg fault or other strange behavior. When I add the good tests in your code it works for me... As example :

if ( p->left && p->right )
cout<<"\n "<<p->data<<" Left: "<<p->left->data<<" Right: "<<p->right->data<<" Parent:" <<p->parent->data<<endl;

or

    if(p->left) {
    std::cout << " Left: "<<p->left->data<< std::endl ;
    inorder(p->left);
}

    if(p->right) {
    std::cout << " Right: "<<p->right->data<< std::endl ;
    inorder(p->right) ;
}
leJon
  • 285
  • 4
  • 10