Создание нового узла для бинарного дерева поиска

Для школьного проекта я пытаюсь создать двоичное дерево поиска, в то же время мы должны научиться использовать «дружбу» в классах. Ошибки, которые я получаю при компиляции: [Я добавляю комментарии в код, откуда возникают ошибки для ясности] (Имейте в виду, что мне не разрешено вкладывать Node в класс BST, они оба должны быть в отдельных файлах и классах для ради этого задания по программированию)

BST.cpp: In member function `void BST::insert(std::string, std::string)':
BST.cpp:51: error: non-lvalue in assignment
BST.cpp:58: error: non-lvalue in assignment
BST.cpp:62: error: non-lvalue in assignment
makefile.txt:9: recipe for target `BST.o' failed
make: *** [BST.o] Error 1

Я пытался использовать «новый» оператор в BST.cpp и Node.cpp, но до сих пор не могу избавиться от этих сообщений об ошибках. Я считаю, что мне может не хватать синтаксиса, который не нравится компилятору. Вот файлы, используемые в этом задании: (Обратите внимание, что некоторые функции еще не используются, так как я не продвинулся так далеко в проекте.) Node.h

#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED

#include <iostream>
#include <string>

using namespace std;

class BST;
class Node
{
public:
    Node(string key, string data)
    {m_key = key; m_data = data;}
    ~Node();
    static string get_key(); //takes in ptr to node and returns its key
    static string get_data(); //takes in ptr to node and returns its data
    static Node* get_left(); //takes in ptr to node and returns its left child pointer
    static Node* get_right(); //takes in ptr to node and returns its right child pointer
    static Node* get_parent(); //takjes in ptr to node and returns its parent pointer
    static Node* create_node(string key, string data);
    static void destroy_node();

private:
    string m_key;
    string m_data;
    Node *m_left;
    Node *m_right;
    Node *m_parent;
};


#endif // NODE_H_INCLUDED

узел.cpp

#include "Node.h"

static string Node::get_key()
{
    return m_key;
}
static string Node::get_data()
{
    return m_data;
}
static Node* Node::get_left()
{
    return m_left;
}
static Node* Node::get_right()
{
    return m_right;
}
static Node* Node::get_parent()
{
    return m_parent;
}
static Node* Node::create_node(string key, string data)
{
    Node* ptr = new Node(key, data);
    ptr->m_left = NULL;
    ptr->m_right = NULL;
    ptr->m_parent = NULL;
    return ptr;
}

Мое намерение до сих пор состоит в том, чтобы Node::create_Node создал новый узел, обнулил все указатели и, наконец, передал указатель узла обратно в BST.cpp, чтобы указатели можно было изменить и вставить в дерево. Ниже приведены BST.cpp и BST.h (для наглядности я добавляю комментарии к местам возникновения ошибок) BST.h:

#ifndef BST_H_INCLUDED
#define BST_H_INCLUDED

#include <iostream>
#include <string>

using namespace std;

class BST
{
public:
    BST()
    {m_root = NULL;}
    ~BST();
    void insert(string key, string data);
    void find(string key);
    void remove(string key, string data);
    void print();
    friend class Node;
private:
    Node* m_root;

};

#endif // BST_H_INCLUDED

Наконец, BST.cpp (где возникают ошибки). Ошибки возникают, когда я пытаюсь изменить указатели z (z — это указатель на новый только что созданный узел), включая его m_left, m_right и m_parent.

#include "BST.h"
#include "Node.h"

void BST::insert(string key, string data)
{
    Node* x = m_root;
    Node* y = NULL;
    Node* z = Node::create_node(key, data);
    while(x != NULL)
    {
        y = x;
        if(key < x->get_key())
        {
            x = x->get_left();
        }
        else
        {
            x = x->get_right();
        }
    }
    z->get_parent() = y; //error: non-lvalue in assignment
    if(y == NULL)
    {
        m_root = z;
    }
    else if(z->get_key() < y->get_key())
    {
        y->get_left() = z; //error: non-lvalue in assignment
    }
    else
    {
        y->get_right() = z; //error: non-lvalue in assignment
    }
}

person user3040019    schedule 27.11.2013    source источник
comment
Результат геттера не является lvalue, вы не можете присвоить ему новое значение. Вместо этого вы хотите присвоить значение самому полю m_left.   -  person flup    schedule 27.11.2013
comment
функции получения не должны быть статическими, у них нет доступа к объекту, для проблемы назначения я бы реализовал функции установки и использовал их   -  person Sigroad    schedule 27.11.2013


Ответы (1)


Если вы хотите использовать возврат get_left() и т. д. в качестве цели для задания, вы должны вернуть ссылку.

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

Node*& Node::get_left()
{
    return m_left;
}
Node*& Node::get_right()
{
    return m_right;
}
Node*& Node::get_parent()
{
    return m_parent;
}

Однако, поскольку цель состоит в том, чтобы научиться использовать дружбу, вам, вероятно, следует просто удалить эти методы и объявить BST как друга Node и предоставить BST прямой доступ к этим полям. Кажется, в этом смысл упражнения.

person john    schedule 27.11.2013
comment
Я пытался сделать их «друзьями», но это все равно не позволяло мне получить доступ к закрытым членам Node из BST. (это было несколько часов назад, трудно вспомнить). Вот почему я сделал эти вспомогательные функции, вы пытаетесь сказать, что мне не нужны вспомогательные функции в Node.cpp или «#include Node.h» в BST.cpp? Вот что меня зацепило, я почти ничего не знаю о наследовании и дружбе. - person user3040019; 27.11.2013
comment
Вы не делаете «их» друзьями, вы делаете класс BST другом класса Node. Все friend class BST; где-то внутри class Node { ... }; - person john; 27.11.2013
comment
Итак, наоборот, поскольку я пытался использовать «дружественный класс Node» в другом файле, и это, похоже, ничего не дало. - person user3040019; 27.11.2013
comment
Да, класс Node дарует дружбу классу BST. Если бы было наоборот, любой класс мог бы просто объявить себя другом любого класса, который ему нравится. - person john; 27.11.2013