你好,我是C ++的新手,正在学习二进制搜索树。 我正在尝试实现一个简单的二进制搜索树,我可以在其中存储“ KeyCodePair”对象(具有字符串和整数),并对树执行一些操作,例如搜索和插入。似乎我的逻辑存在一些问题,这就是为什么第一个Insert函数起作用但第二个不起作用(从Main调用)的原因,我猜我在哪里应该实现“ root”的方式存在问题
这是Tree.cpp:
#include "Tree.h";
#include "KeyCodePair.h";
Tree::Tree() {
treeNode* root = NULL;
}
Tree::treeNode* Tree::getNewNode(KeyCodePair data) {
treeNode* newNode = new treeNode();
newNode->data = data;
newNode->left = newNode->right = NULL;
return newNode;
}
Tree::treeNode* Tree::Insert(KeyCodePair data) {
if (root == NULL) {
root = getNewNode(data);
}
else if (data.getCode() <= root->data.getCode()) {
root->left = Insert(data);
}
else {
root->right = Insert(data);
}
return root;
}
bool Tree::Search(KeyCodePair data) {
if (root == NULL) {
return false;
}
else if (root->data.getCode() == data.getCode()) {
return true;
}
else if (data.getCode() <= root->data.getCode()) {
return Search(data);
}
else {
return Search(data);
}
}
Tree.h:
#ifndef TREE_H
#define TREE_H
#include "KeyCodePair.h"
class Tree {
private:
struct treeNode {
KeyCodePair data;
treeNode* left;
treeNode* right;
} ;
treeNode* root;
public:
treeNode* Insert( KeyCodePair data);
bool Search(KeyCodePair data);
treeNode* getNewNode(KeyCodePair data);
Tree();
};
#endif
KeyCodePair.cpp
#include "KeyCodePair.h"
KeyCodePair::KeyCodePair(string keyparam, int codeparam) {
key = keyparam;
code = codeparam;
}
KeyCodePair::KeyCodePair() {
}
string KeyCodePair::getKey() {
return key;
}
int KeyCodePair::getCode() {
return code;
}
KeyCodePair.h
#ifndef KEYCODEPAIR_H
#define KEYCODEPAIR_H
#include <iostream>
using namespace std;
class KeyCodePair {
private:
string key;
int code;
public:
KeyCodePair();
KeyCodePair(string key, int code);
string getKey();
int getCode();
};
#endif
最后这是主要内容:
#include <iostream>
#include <string>
#include "Tree.h"
#include "KeyCodePair.h"
using namespace std;
int main()
{
Tree tree = Tree();
KeyCodePair testPair = KeyCodePair("teststring1",10);
KeyCodePair qwePair = KeyCodePair("teststring2", 20);
cout << tree.Insert(testPair) << endl;
cout << tree.Insert(qwePair) << endl; // problem on second insert
if (tree.Search(testPair) == true) cout << "Found\n";
else cout << "Not Found\n";
cin.get();
return 0;
}
答案 0 :(得分:1)
让我们看一下您的插入函数:
Tree::treeNode* Tree::Insert(KeyCodePair data) {
if (root == NULL) {
root = getNewNode(data);
}
else if (data.getCode() <= root->data.getCode()) {
root->left = Insert(data);
}
else {
root->right = Insert(data);
}
return root;
}
您要做的是将要插入的数据放入数据库中,然后查看根目录。如果没有根,则添加一个包含数据的新节点,并将其分配给根(这就是您第一次插入工作的原因)。但是,一旦有了根,就可以确定是将新节点放置在根的左侧还是右侧,然后使用相同的数据递归调用Insert()。接下来的对Insert的调用不会有任何不同,并且一遍又一遍地查看树的同一根,很可能会产生无限循环。
您需要做的是使用数据,首先一直沿树向下遍历到要插入节点的位置,然后将其插入并分配指针。一些代码可能看起来像这样:
Tree::Insert(KeyCodePair data) {
// currPos will end up being the position where we want to insert
Tree::treeNode* currPos = root;
while (currPos != NULL) {
if (data.getCode() <= currPos->data.getCode())
currPos = currPos->left;
else if (data.getCode() > currPos->data.getCode())
currPos = currPos->right;
}
// Insert at currPos and reassign the left or right pointer of
// the parent
}
答案 1 :(得分:0)
问题是您的插入内容仅考虑根节点。您需要遍历树到进行插入的位置:
class Tree {
...
public:
treeNode* Insert(KeyCodePair data);
...
};
第1步:更改界面
class Tree {
...
// The insert that does the work
// We pass in the current position in the tree.
treeNode* Insert(treeNode* node, KeyCodePair data);
public:
// The public interface that accepts the data and calls the internal Insert
void Insert(KeyCodePair data);
...
};
第2步:使用公共插入程序调用内部插入程序。
void Tree::Insert(KeyCodePair data) {
// Use the internal Insert() passing the root as the starting point.
// If a new value is needed it will be returned otherwise the original
// value is returned.
root = Insert(root, data);
}
第3步:将OP插件修改为内部插件。
Tree::treeNode* Tree::Insert(treeNode* node, KeyCodePair data) {
if (node == NULL) {
// If we have reached the tip of the tree then
// return the new node so it can be inserted.
return getNewNode(data);
}
// Otherwise we have a node so we need to find the node
// were the data will be inserted.
// so move to the next level. Assign the result as the next
// level could be null.
if (data.getCode() <= root->data.getCode()) {
node->left = Insert(node->left, data);
}
else {
node->right = Insert(node->right, data);
}
// Return this node
// So it stays in the chain.
return node;
}