【问题标题】:Node is null even though it has a value?节点是空的,即使它有一个值?
【发布时间】:2020-01-22 10:04:39
【问题描述】:

我正在尝试基于整数数组创建二叉搜索树。

我创建了一个函数 BST,它接受一个数组及其大小作为参数。现在我在数组的每个项目上调用另一个函数 makeBST ,它采用根节点和那个值。它创建另一个节点并根据该值将其附加到根节点。

但 makeBST 函数并没有在自身上递归并为数组的每个值执行 NULL 条件,即使根节点不为 null

#include<iostream>
#include<cmath>

using namespace std;

class Node {

    public:
    int data;
    Node *left;
    Node *right;
};

Node *newNode(int x){

    Node *node = new Node();
    node->data = x;
    node->left=NULL;
    node->right = NULL;
    return node;
};


void makeBST(Node *node, int x){

    if(node==NULL){
        // keep getting executed even though root node has a value.
        // here must be error.

        cout << " NULL condition " << endl;
        node = newNode(x);
        return;
    };
    if((node->data) > x){
        cout << "also working" << endl;
        makeBST(node->left,x);
    }else if((node->data) < x){
        makeBST(node->right,x);
    };
};

Node *BST(int arr[], int n){

    Node *root = newNode(arr[0]);
    for(int i=1; i<=n-1; i++){
        cout << "loop" << i << endl;
        makeBST(root,arr[i]);
    };
    return root;
};

int main(){

    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    int n=10;
    Node *root = BST(arr,n);

    return 0;
};

我知道这不是创建二叉搜索树的最佳方式。但我是初学者,这是我能想到的。

谁能帮忙?

【问题讨论】:

  • node = newNode(x); in makeBST 只会泄漏内存。您正在更改 node 指针变量的 local 值,但在调用站点上看不到该更改。当您使用p == nullptr 调用makeBST(p, x) 时,之后p 仍将是nullptr。尝试使用 Node*&amp; node 代替 makeBST 参数。然后确保了解为什么会这样。
  • 另外,每个if (...) { ... } 后面的; 也不需要。你必须deletenew
  • 除了手头的实际问题,请问您为什么使用像结构这样的类?你的newNode 函数看起来应该是Node 的构造函数,而makeBST 也感觉像一个方法。
  • @MaxLanghof 你是什么意思?不使用';'是否会删除在 if else 条件下创建的临时空间?我是初学者,所以请原谅我的知识。
  • 旁白:例子中你的树也是一个列表,你只分配Node *rights

标签: c++ algorithm c++11 data-structures


【解决方案1】:

目前,您正在更改函数中 (*node) 的本地值,而不会对传递给它的变量 node 产生任何影响。您应该阅读有关将指针作为值传递与作为引用传递的内容。

如果您想更改node,您需要将其作为参考传递:

void makeBST(Node **node, int x) {

    if(*node==NULL){
        cout << " NULL condition " << endl;
        node = &newNode(x);
        return;
    };
    if((*node->data) > x){
        cout << "also working" << endl;
        makeBST(&(*node->left),x);
    }else if((*node->data) < x){
        makeBST(&(*node->right),x);
    };
};

确保在调用makeBST时传递了节点的地址。

【讨论】:

  • 谢谢。有效。但我有一个问题。我研究过按值传递和按引用传递。在链表中附加一个节点时,我们只通过值传递头节点,如head,并在附加函数中以Node *head 接受它,但新节点仍然成功附加到链表中。为什么我们不通过&amp;head,我的意思是&amp;head 可以工作,但head 也可以?如果你回答这个问题会很有帮助。
  • @PrateekGautam - 当一个函数改变你得到的对象的一个​​成员时,例如,如果函数得到head并改变了head-&gt;left的值,那么就可以通过值得到head .另一方面,当您需要更改对象本身时,例如,当您获得 head 并想要替换 head 时,您必须通过引用来获取它,否则您只需更改函数范围 head .
  • 非常感谢。我现在明白了。
猜你喜欢
  • 2018-12-20
  • 1970-01-01
  • 2016-05-21
  • 2019-11-11
  • 2018-05-15
  • 2022-01-22
  • 1970-01-01
  • 2018-03-05
  • 1970-01-01
相关资源
最近更新 更多