繁体   English   中英

为什么我不能返回指向我的 BST 树结构节点的指针? C++

[英]Why can't I return pointer to a node of my BST tree structure? C++

我正在编写一个 BST 树,首先我使用 integer 键,一切正常。 然后我复制了我的代码并进行了一些更改,我将 integer 键切换为字符串键,并添加了一个新指针(因为我的目标是创建两棵树,一棵带有英语单词,一棵带有波兰语翻译)所以我只是在首先具有字符串键的单树并插入 function 就像在整数树中一样工作正常,但是搜索 function 正在返回一些由 NULL 或指针插入的垃圾。 我真的不知道这里有什么问题。

我把 Integer 树的代码放在下面:

#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
using namespace std;

        typedef struct BST
    {
        int key;
        BST* right;
        BST* left;
    }BST_node;
    
    BST_node* CreateNewNode(int data)  // function that returns new node of my tree
    {
        BST_node* NewNode = new BST_node;
        NewNode->key = data;
        NewNode->right = NULL;
        NewNode->left = NULL;
        return NewNode;
    }
    
    BST_node* bstSearch(BST_node* root, int data) // search function
    {
        if (root == NULL)
            return NULL;
    
        else if (root->key == data)
            return root;
    
        else if (root->key < data)
            bstSearch(root->right, data);
    
        else
            bstSearch(root->left, data);
    }
    
    void bstInsert(BST_node*& root, int data) // insert function
    {
        if (root == NULL)
            root = CreateNewNode(data);
        
        if (data < root->key) 
            bstInsert(root->left, data); 
    
        else if (data > root->key) 
            bstInsert(root->right, data); 
    }
            
    int main()
    {
        ifstream in1("InTest1.txt"); // InTest1.txt:1 2 4 3 5 52 2 4
        BST_node* root = NULL;
        int suppVar;
        while (!in1.eof())
        {
            in1 >> suppVar;
            bstInsert(rootEng, suppVar);
        }
        BST_node* tmp = bstSearch(rootEng, 2);
        if (tmp == NULL)
            cout << "There is no element with given key";
        else
            cout << "key = " << tmp->key;
        
    }

OUT: key = 2

我还把我的树的字符串键版本的代码放在下面:

#include <iostream>
#include <fstream>
#include <string.h>
#include <string>
using namespace std;

typedef struct BST_str
{
    string key;
    BST_str* right;
    BST_str* left;
    BST_str* engWordPtr; // pointer to node in translation tree (not used yet)
}BST_strNode;

BST_strNode* CreateNewStrNode(string data) // function that returns new node of my tree
{
    BST_strNode* NewNode = new BST_strNode;
    NewNode->key = data;
    NewNode->right = NULL;
    NewNode->left = NULL;
    NewNode->engWordPtr = NULL;
    return NewNode;
}

BST_strNode* bstStrSearch(BST_strNode* root, string data) // search function
{
    if (root == NULL)
        return NULL;

    else if (strcmp(root->key.data(), data.data()) == 0)
        return root;

    else if (strcmp(root->key.data(), data.data()) < 0)
        bstStrSearch(root->right, data);

    else if (strcmp(root->key.data(), data.data()) > 0)
        bstStrSearch(root->left, data);
}

void bstStrInsert(BST_strNode*& root, string data) // insert function
{
    if (root == NULL)
        root = CreateNewStrNode(data);

    else if (strcmp(root->key.data(), data.data()) > 0) 
        bstStrInsert(root->left, data);

    else if (strcmp(root->key.data(), data.data()) < 0)
        bstStrInsert(root->right, data);
}

int main()
{
    ifstream in1("InTest2.txt"); // InTest2.txt:O G X E OH D F I OA H OB OX
    BST_strNode* rootEng = NULL;
    string suppVar;
    while (!in1.eof())
    {
        in1 >> suppVar;
        bstStrInsert(rootEng, suppVar);
    }
    BST_strNode* tmp = bstStrSearch(rootEng, "OXcasdf");
    if (tmp == NULL)
        cout << "There is no element with given key";
    else
        cout << "key = " << tmp->key;
}

OUT: key =

并且程序崩溃,我是否要搜索已经存在的字符串并不重要,总是相同的结果,可能它返回一些垃圾而不是节点或 NULL 但我真的不知道为什么它在 integer 树上工作,但在字符串树上没有。 它还会生成 3 个警告:

Warning C26495 Variable 'BST_str::engWordPtr' is uninitialized. Always initialize a member variable (type.6).

Warning C26495 Variable 'BST_str::left' is uninitialized. Always initialize a member variable (type.6).

Warning C26495 Variable 'BST_str::right' is uninitialized. Always initialize a member variable (type.6).

调试时也出现异常:

Exception thrown: read access violation. this was 0x45.

我在这里先向您的帮助表示感谢。

递归 function bstSearch是不正确的,因为它没有在每个执行路径中返回一个节点

BST_node* bstSearch(BST_node* root, int data) // search function
{
    if (root == NULL)
        return NULL;

    else if (root->key == data)
        return root;

    else if (root->key < data)
        bstSearch(root->right, data);

    else
        bstSearch(root->left, data);
}

最后一个 if else 语句应该看起来像

    else if (root->key < data)
        return bstSearch(root->right, data);

    else
        return bstSearch(root->left, data);

同样对于为字符串设计的 function 也无需使用 C function strcmp。 function 可以通过以下方式定义

BST_strNode* bstStrSearch( BST_strNode* root, const string &data) // search function
{
    if (root == NULL)
        return NULL;

    else if ( root->key == data )
        return root;

    else if ( root->key < data )
        return bstStrSearch(root->right, data);

    else 
        return bstStrSearch(root->left, data);
}

注意while循环的条件

while (!in1.eof())
{
    in1 >> suppVar;
    bstStrInsert(rootEng, suppVar);
}

是不正确的。 在此语句之后可以出现 eof state

    in1 >> suppVar;

相反,你应该写

while ( in1 >> suppVar)
{
    bstStrInsert(rootEng, suppVar);
}

请注意,编译时,编译器应打印如下警告:

警告:控制可能到达非无效 function 的末尾

参考bstStrInsert 实际上,查看 function 定义,两个递归分支不返回值。

为了防止警告(以及一般的此类错误),您可以使用局部变量来保存结果,并有一个返回值。

此外,函数应重写为 BST 节点 class 的成员 function。 您还可以使用模板(和模板特化),而不是为每个键类型创建单独的、不相关的 BST 类。

BST_Node<String>* BST_Node<String>::search(BST_strNode* root, string data) // search function
{
    BST_Node<String>* result = NULL;

    if (root) {
        if (root->key == data)
            result = root;
        else if (root->key < data)
            result = bstStrSearch(root->right, data);
        else if (root->key > data)
            result = bstStrSearch(root->left, data);
    }

    return result;
}

额外的

打印消息时,请确保包含换行符。 这可以通过字符串中的换行符来完成,但更好的是 output std::endl ,这也会刷新 output 缓冲区(如果 output 可能是缓冲的)。

将所有std导入到当前命名空间中对于一次性、示例和练习代码都很好,但不应该在生产中完成。 导入特定符号(例如std::cinstd::coutstd::endl )很好并且不太可能导致冲突。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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