Nano Hash - криптовалюты, майнинг, программирование

Двоичное дерево сортировки — получение значения из ячейки памяти

Привет, ребята, просто возникли проблемы с распечаткой для родителя и братьев и сестер каждого узла в дереве. Вот полный блок кода

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

поэтому проблема, с которой я сталкиваюсь, заключается в том, что родитель и братья и сестры распечатываются как ячейки памяти, и если значение должно быть нулевым, оно печатает все 0, что заставляет меня думать, что это работает, и что мне просто нужно выяснить как получить эти ячейки памяти.

Теперь я немного поискал и нашел этот пост в stackoverflow. конкретный адрес памяти

это то, что я пробовал

//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 Я не могу публиковать изображения, поэтому я не могу публиковать вывод.

РЕДАКТИРОВАТЬ: ВЫВОД

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

Как вы можете видеть, где когда-либо числа совпадают, ячейки памяти также совпадают, что подтверждает тот факт, что он работает, просто нужно получить числа, а не адрес памяти.


  • Почему бы вам просто не прочитать p->data после того, как вы только что записали int в это место? Что должен делать reinterpret_cast<int*>(p->left)? 29.04.2014
  • Насколько я понимаю из того, что здесь написано -> stackoverflow.com/questions/12298208/ предполагается, что он уважает адрес памяти. 29.04.2014
  • Что выводит первая строка после вашего закомментированного кода? 29.04.2014

Ответы:


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  
29.04.2014
  • Спасибо, мне удалось поговорить с моим профессором, и она указала на то же самое, что я не проверял на Null, а также на данные, которые мне не хватало. Я ценю помощь. 29.04.2014

  • 2

    у вас явно есть проблема в этой части кода:

    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 равно нулю, ваш код выдаст ошибку сегмента или другое странное поведение. Когда я добавляю хорошие тесты в ваш код, это работает для меня... Например:

    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) ;
    }
    
    29.04.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..