【问题标题】:I wanted to implement a BST and tried using vector for input我想实现一个 BST 并尝试使用向量作为输入
【发布时间】:2021-07-31 18:22:49
【问题描述】:

我想用向量实现一个 BST 类,但不知何故它不起作用。我只是想知道它不起作用的原因。

我能想到 BST 中的那个根始终保持 NULL 的主要原因。

我想尝试在数据结构中使用类的方法。

#include<iostream>
#include<vector>

using namespace std;

class Node{
    public:
    int data;
    Node* left ;
    Node* right ;

    Node(int val){
        data = val;
        left = NULL;
        right = NULL;
    }
};


class BST{
    public:
    Node* root = NULL;

    void insert(Node* r,int data){
        Node* new_node = new Node(data);
        if(r == NULL){
            r = new_node;
        }

        if(data < r->data){
            if(r->left == NULL){
                r->left = new_node;
            }
            else{
                insert(r->left,data);
            }
        }else if(data > r->data){
            if(r->right == NULL){
                r->right = new_node;
            }
            else{
                insert(r->right,data);
            }
        }else{
            return;
        }
        return;
    }

    BST(vector<int> bst_array){
        for(int i = 0; i<bst_array.size(); i++){
            insert(root,bst_array[i]);
        }
    }

    void print_t(Node* r){
        if(r == NULL){
            cout<<"NULL";
            return;
        }
            
        else{
            print_t(r->left);
            cout<<r->data<<" ";
            print_t(r->right); 
        }
    }
    
};


int main(){

    vector<int> v = {1,3,5,44,23,78,21};

    BST* tr = new BST(v);

    tr->print_t(tr->root);

    return 0;
}

我这边好像有逻辑错误,请帮我找出来。

提前致谢。

【问题讨论】:

  • 你的调试器说什么?
  • 什么都没有。它只是每次都进入 if(r == NULL) [print_t(Node* r) 语句。
  • 然后上一步了解为什么 r 是一个空指针,而你不希望是空指针。
  • 因为r = new_node 中的insert 最终对函数的调用者意味着nothingr 按值传递给 insert。更改它不会影响调用者对该值的调用副本。 root 在通话后仍然为空,而且作为奖励,您泄漏内存只是为了在伤口上撒盐。
  • “它不工作” - 这是对您的问题的无用描述,涵盖了从编译失败到意外释放 Skynet 的所有内容。什么具体不起作用?您观察到什么让您相信存在错误?

标签: c++ tree c++14 binary-tree


【解决方案1】:

原因是root 在初始化为NULL 后从未被赋予另一个值。将root 作为参数传递给insert 方法永远不会改变root 本身,因为传递的不是root 的地址,而是它的值。

其他一些评论:

  • insert 总是从创建一个新节点开始,在递归的每一步。这是对节点创建的浪费。最后你只需要一个新节点,所以只有当它在树中的位置已经确定时才创建它。

  • 不需要最后的else,因为它所做的只是执行return,如果没有else 块,它无论如何都会这样做

  • 由于insertBST的一个方法,可惜它需要一个节点作为参数。你真的很想只做insert(data) 并让它处理它。为此,我建议将您的 insert 方法移动到 Node 类,其中 this 节点将接管参数的角色。然后BST 类可以得到一个包装insert 方法,将作业转发给另一个insert 方法。

  • nullptr代替NULL

要解决主要问题,有很多可能的解决方案。但是在进行上述更改后,在BST 类的简化insert 方法中分配给root 是相当容易的。

这是它的工作原理:

class Node{
    public:
    int data;
    Node* left ;
    Node* right ;

    Node(int val){
        data = val;
        left = nullptr;
        right = nullptr;
    }

    void insert(int data) {
        if (data < this->data) {
            if (this->left == nullptr) {
                this->left = new Node(data);
            } else {
                this->left->insert(data);
            }
        } else if (data > this->data) {
            if (this->right == nullptr) {
                this->right = new Node(data);
            } else {
                this->right->insert(data);
            }
        }
    }
};

class BST {
    public:
    Node* root = nullptr;

    void insert(int data) {
        if (root == NULL) { // Assign to root
            root = new Node(data);
        } else { // Defer the task to the Node class
            root->insert(data);
        }
    }

    BST(vector<int> bst_array){
        for(int i = 0; i<bst_array.size(); i++){
            insert(bst_array[i]); // No node argument
        }
    }

    /* ...other methods ...*/
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 2021-07-26
    • 2020-08-15
    相关资源
    最近更新 更多