[英]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::cin
、 std::cout
和std::endl
)很好并且不太可能导致冲突。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.