简体   繁体   中英

Rooted binary search tree. Keeping a link to its parent

I'm trying to create a binary search tree by keeping the path: each node has a link to its parent. Below is the classic binary search. How do I change it to be able to solve my problem? I tried adding the "father" pointer to the struct but I have no problems understanding how and when to save it. I am new to this language so be patient. thank you so much

#include <iostream>

template <class T>
class BinaryTree
{

    struct node {
        T value;
        struct node* right;
        struct node* left;
    };

public:
    BinaryTree();
    ~BinaryTree();
    void add(T val);
    void printPreOrder();
    void printInOrder();
    void printPostOrder();
    int size();
    bool lookup(T val);

private:
    struct node* root;
    int treeSize;
    void add(struct node** node, T val);
    bool lookup(struct node* node, T val);
    void printPreOrder(struct node* node);
    void printInOrder(struct node* node);
    void printPostOrder(struct node* node);
    void deleteTree(struct node* node);
};

template <class T>
BinaryTree<T>::BinaryTree() {
    this->root = NULL;
    this->treeSize = 0;
}

template <class T>
BinaryTree<T>::~BinaryTree() {
    deleteTree(this->root);
}

template <class T>
int BinaryTree<T>::size() {
    return this->treeSize;
}

template <class T>
void BinaryTree<T>::add(T val) {
    add(&(this->root), val);
}

template <class T>
void BinaryTree<T>::add(struct node** node, T val) {

    if (*node == NULL) {
        struct node* tmp = new struct node;
        tmp->value = val;
        tmp->left = NULL;
        tmp->right = NULL;
        *node = tmp;

        this->treeSize++;
    }
    else {
        if (val > (*node)->value) {
            add(&(*node)->right, val);
        }
        else {
            add(&(*node)->left, val);
        }
    }
}

template <class T>
void BinaryTree<T>::printInOrder() {
    printInOrder(this->root);
    std::cout << std::endl;
}

template <class T>
void BinaryTree<T>::printInOrder(struct node* node) {
    if (node != NULL) {
        printInOrder(node->left);
        std::cout << node->value << ", ";
        printInOrder(node->right);
    }
}

template <class T>
void BinaryTree<T>::printPreOrder() {
    printPreOrder(this->root);
    std::cout << std::endl;
}

template <class T>
void BinaryTree<T>::printPreOrder(struct node* node) {
    if (node != NULL) {
        std::cout << node->value << ", ";
        printInOrder(node->left);
        printInOrder(node->right);
    }
}

template <class T>
void BinaryTree<T>::printPostOrder() {
    printPostOrder(this->root);
    std::cout << std::endl;
}

template <class T>
void BinaryTree<T>::printPostOrder(struct node* node) {
    if (node != NULL) {
        printInOrder(node->left);
        printInOrder(node->right);
        std::cout << node->value << ", ";
    }
}


template <class T>
void BinaryTree<T>::deleteTree(struct node* node) {
    if (node != NULL) {
        deleteTree(node->left);
        deleteTree(node->right);
        delete node;
    }
}

template <class T>
bool BinaryTree<T>::lookup(T val) {
    return lookup(this->root, val);
}

template <class T>
bool BinaryTree<T>::lookup(struct node* node, T val) {
    if (node == NULL) {
        return false;
    }
    else {
        if (val == node->value) {
            return true;
        }

        if (val > node->value) {
            return lookup(node->right, val);
        }
        else {
            return lookup(node->left, val);
        }
    }

}

I will give you the recursive solution since it is the natural way to implement it: First it would be a good idea to define a constructor in your struct like so:

node(T value, node* left = nullptr, node* right = nullptr){
    this->value = value;
    this->left = left;
    this->right = right;
}

Take out the struct in the struct node* root.

void insert(T value){
    Node* temp = root;
    insert(value, root);
}
//helper function
void insert(T value, Node* root){
    if(root->left == nullptr && root->right == nullptr){
       if(root->value < value){
          root->left = new Node(value);
       }
       else{
          root->right = new Node(value);
       }
       return;
    }
    if(value < root->value)insert(value, root->left);
    else{
        insert(value, root->right);
    }
}

Not sure where you got your code it does not look correct....

I don't understand the need for pointer to pointer to struct node in your code. Pointer to struct node would suffice. As far as your question goes, you can pass the parent of current node as a third parameter in the method add . Initially it will be null. Now incase you have to go down to the child of the current node, then the current node becomes it's parent. When you have to allocate memory for value val , set the it's parent there.

template <class T>
void BinaryTree<T>::add(struct node** node, T val, struct node* parent = nullptr) {

    if (*node == NULL) {
        struct node* tmp = new struct node;
        tmp->value = val;
        tmp->left = NULL;
        tmp->right = NULL;
        temp->parent = parent;
        *node = tmp;

        this->treeSize++;
    }
    else {
        if (val > (*node)->value) {
            add(&(*node)->right, val, *node);
        }
        else {
            add(&(*node)->left, val, *node;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM