Двоичное дерево C ++ с 3 значениями для структуры - PullRequest
0 голосов
/ 02 мая 2018

Итак, я пытаюсь создать двоичное дерево поиска, в котором хранится идентификатор (T value), возраст (int age) и имя (string) для каждого «пузыря», расположенного в дереве, и сортируется по идентификатору.

По какой-то причине я не могу заставить свой код правильно хранить все 3 значения как 1 структуру на узел. Что-то я делаю не так?

Вот мой код.

#ifndef _TREE_GUARD 
#define _TREE_GUARD 1

#include <iostream>
#include <math.h>
using namespace std;

template <class T>
struct Node {
    T value;
    int age;
    string name;
    Node *left;
    Node *right;

    Node(T val) {
        this->value = val;
    }

    Node(T val, int age, string name, Node<T> left, Node<T> right) {
        this->value = val;
        this->age = age;
        this->name = name;

        this->left = left;
        this->right = right;
    }
};

template <class T>
class BST {

private:
    Node<T> *root;

    void addHelper(Node<T> *root, T val) {
        if (root->value > val) {
            if (!root->left) {
                root->left = new Node<T>(val);
            }
            else {
                addHelper(root->left, val);
            }
        }
        else {
            if (!root->right) {
                root->right = new Node<T>(val);
            }
            else {
                addHelper(root->right, val);
            }
        }
    }

    void printHelper(Node<T> *root) {
        if (!root) return;
        printHelper(root->left);
        cout << root->value << ' ';
        cout << root->age << ' '; // ADDED
        cout << root->name << ' '; //ADDED
        printHelper(root->right);
    }

    int nodesCountHelper(Node<T> *root) {
        if (!root) return 0;
        else return 1 + nodesCountHelper(root->left) + nodesCountHelper(root->right);
    }

    int heightHelper(Node<T> *root) {
        if (!root) return 0;
        else return 1 + max(heightHelper(root->left), heightHelper(root->right));
    }

    void printMaxPathHelper(Node<T> *root) {
        if (!root) return;
        cout << root->value << ' ';
        if (heightHelper(root->left) > heightHelper(root->right)) {
            printMaxPathHelper(root->left);
        }
        else {
            printMaxPathHelper(root->right);
        }
    }

    bool deleteValueHelper(Node<T>* parent, Node<T>* current, T value) {
        if (!current) return false;
        if (current->value == value) {
            if (current->left == NULL || current->right == NULL) {
                Node<T>* temp = current->left;
                if (current->right) temp = current->right;
                if (parent) {
                    if (parent->left == current) {
                        parent->left = temp;
                    }
                    else {
                        parent->right = temp;
                    }
                }
                else {
                    this->root = temp;
                }
            }
            else {
                Node<T>* validSubs = current->right;
                while (validSubs->left) {
                    validSubs = validSubs->left;
                }
                T temp = current->value;
                current->value = validSubs->value;
                validSubs->value = temp;
                return deleteValueHelper(current, current->right, temp);
            }
            delete current;
            return true;
        }
        return deleteValueHelper(current, current->left, value) ||
            deleteValueHelper(current, current->right, value);
    }

public:

    void insert(T val) {
        if (root) {
            this->addHelper(root, val);
        }
        else {
            root = new Node<T>(val);
        }
    }

    void print() {
        printHelper(this->root);
    }

    int nodesCount() {
        return nodesCountHelper(root);
    }

    int height() {
        return heightHelper(this->root);
    }

    void printMaxPath() {
        printMaxPathHelper(this->root);
    }

    bool Delete(T value) {
        return this->deleteValueHelper(NULL, this->root, value);
    }
};
#endif

Я создал структуру, используя эти 3 значения и указатель на правый и левый узлы, однако все остальные мои функции, похоже, не работают со значениями возраста и имени, только с идентификатором. Это наиболее проблематично в моей функции add и print.

Я относительно новичок в C ++, поэтому любая помощь будет принята.

РЕДАКТИРОВАТЬ: Я предполагаю, что моя проблема лежит где-то здесь. Код работает просто отлично, но он не добавляет возраст и имя к строке, и я не могу правильно распечатать эти значения, только ID

 Node<T> *root;

    void addHelper(Node<T> *root, T val) {
        if (root->value > val) {
            if (!root->left) {
                root->left = new Node<T>(val);
            }
            else {
                addHelper(root->left, val);**
            }
        }
        else {
            if (!root->right) {
                root->right = new Node<T>(val);
            }
            else {
                addHelper(root->right, val);
            }
        }
    }

и здесь

void printHelper(Node<T> *root) {
        if (!root) return;
        printHelper(root->left);
        cout << root->value << ' ';
        cout << root->age << ' '; // ADDED
        cout << root->name << ' '; //ADDED
        printHelper(root->right);
    }

Заранее спасибо!

1 Ответ

0 голосов
/ 02 мая 2018

root-> left = new Node (val);

root-> right = new Node (val);

Кажется, что вы создаете новый узел и даете ему только "val", без возраста, имени и т. Д., Поэтому он имеет только значение.

edit: я никогда не использовал "Template" раньше, поэтому мне понадобилось время, чтобы разобраться с ним. В любом случае ...

Решение: Когда вы вставляете узел, вам нужно скопировать всю информацию, а не только «значение», иначе вы получите только «значение».

void addHelper(Node<T> *root, Node<T>* n) {
    if (root->value > n->value) {
        if (!root->left) {
            root->left = new Node<T>(n->value,n->age,n->name,NULL,NULL);
        }
        else {
            addHelper(root->left, n);
        }
    }
    else {
        if (!root->right) {
            root->right = new Node<T>(n->value,n->age,n->name,NULL,NULL);
        }
        else {
            addHelper(root->right, n);
        }
    }
}

Также в «insert»:

void insert(Node<T>* n) {
    if (root) {
        this->addHelper(root, n);
    }
    else {
        root = new Node<T>(n->value,n->age,n->name,NULL,NULL);
    }
}

Несколько других вещей, которые вы можете попробовать и увидеть разницу:

Я бы инициализировал * root как NULL, в противном случае это может быть какой-то случайный материал, и иногда я получаю ошибку seg из-за этого.

class BST {

private:
    Node<T> *root=NULL;

Если узел, который вы собираетесь вставить, имеет то же самое «значение» с уже существующим узлом, что вы делаете? Ваша программа просто добавит его справа. Я не знаю, хотите ли вы этого, но именно так оно и будет.

Я проверил с этим, и это сработало. Надеюсь, это сработает и для вас.

int main(){
    BST<int> tree;
    Node<int> node1(1,10,"test1",NULL,NULL);
    Node<int> node2(5,50,"test2",NULL,NULL);
    Node<int> node3(3,30,"test3",NULL,NULL);
    Node<int> node4(3,30,"test4",NULL,NULL);
    Node<int> node5(3,30,"test5",NULL,NULL);
    Node<int> node6(8,80,"test5",NULL,NULL);
    tree.insert(&node1);
    tree.insert(&node2);
    tree.insert(&node3);
    tree.insert(&node4);
    tree.insert(&node5);
    tree.insert(&node6);
    tree.print();
    cout<<endl;
    return 0;
}

выход:

1 10 test1 3 30 test3 3 30 test4 3 30 test5 5 50 test2 8 80 test5 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...