二进制排序树 - 从内存位置获取值

时间:2014-04-29 16:43:24

标签: c++ pointers data-structures binary-search-tree

嘿,伙计们只是在为树中每个节点的父节点和兄弟节点打印输出时遇到一些问题。 这是完整的代码块

/*
---------------
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;
       }
    }
}

所以我遇到的问题是父母和兄弟姐妹都打印出来作为内存位置,如果该值应该为null,则打印出所有0,这让我认为它正在工作,我只需要找出如何获取这些内存位置。

现在我做一些搜索,并在stackoverflow上发现这篇文章 C++ - Get value of a particular memory address

这就是我尝试过的

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

我评论了该程序的一部分,因为它不起作用。我将不胜感激任何帮助。 输入:10 20 8 4 5 15 17 2 我无法发布图片,所以我无法发布输出。

编辑: 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

但它应该是

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

正如您所看到的那样,数字匹配的内存位置也匹配,这支持了它正在工作的事实只需要获取数字而不是内存地址。

2 个答案:

答案 0 :(得分:1)

在文件顶部添加#include <iomanip>以格式化输出,就像我在这个答案中所做的那样:

您只是不检查指针是否有效。如果指向子节点的指针为NULL,那么您无法访问那里的data属性,因为还没有为它分配内存。

此外,请记住,如果您发现自己需要在内存中访问原始地址而不是使用简单的指针,那么您很可能会做错事/做得很难。

只需检查子/父节点是否为空。

setw(4)left将宽度设置为4,并将输出格式化为左对齐。

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

插入后:

 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  

答案 1 :(得分:0)

你在这部分代码中显然有问题:

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;

如果p->left为空,则代码会产生seg错误或其他奇怪的行为。当我在你的代码中添加好的测试时,它对我有用...... 例如:

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

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