我使用这段代码创建一个新节点并将其插入二叉搜索树。它正确插入根,与其第一个右和左子项相同,但之后的任何内容似乎都替换了现有的子项。
例如:
7
2 15
如果我现在插入10,它将替换15而不是生成其左孩子。
Node * createNode(Element elem)
{
Node * newNode = new Node;
newNode->elem = elem;
newNode->left = nullptr;
newNode->right = nullptr;
newNode->parent = nullptr;
return newNode;
}
bool insertElem(BST & tree, Element elem)
{
Node * newNode = createNode(elem);
if (!tree.root)
{
tree.root = newNode;
return true;
}
else
{
return insertElem(newNode, tree.root);
}
}
bool insertElem(Node * node, Node * root)
{
if (node->elem.key == root->elem.key) return false; // already exists
if (node->elem.key > root->elem.key) // goes to the right
{
if (root->right) insertElem(node, root->right);
node->parent = root;
root->right = node;
return true;
}
if (node->elem.key < root->elem.key) // goes to the left
{
if (root->left) insertElem(node, root->left);
node->parent = root;
root->left = node;
return true;
}
return false;
}
答案 0 :(得分:0)
左右右倾的逻辑应该不盲目地覆盖root->left
和/或root->right
。在知道你要插入树之前,你也不应该分配一个新节点。最后,引用point(或指针指针,但毕竟这是C ++)使算法更容易理解:
一般递归插入如下所示:
#include <iostream>
#include <random>
struct Node
{
int value;
Node *left;
Node *right;
Node(int arg) : value(arg), left(), right()
{
}
};
void insertElem(Node *& root, int value)
{
if (root)
{
if (value < root->value )
insertElem(root->left, value);
else if (root->value < value)
insertElem(root->right, value);
// else equivalent, do nothing
}
else
{
root = new Node(value);
}
}
void inorder(const Node* root)
{
if (!root)
return;
inorder(root->left);
std::cout << root->value << ' ';
inorder(root->right);
}
void delete_tree(Node *& root)
{
if (root)
{
delete_tree(root->right);
delete_tree(root->left);
delete root;
root = nullptr;
}
}
int main()
{
std::random_device rd;
std::mt19937 rng(rd());
std::uniform_int_distribution<> dist(1,10);
Node *root = nullptr;
for (size_t i=0; i<10; ++i)
{
int value = dist(rng);
std::cout << value << ' ';
insertElem(root, value);
}
std::cout.put('\n');
inorder(root);
std::cout.put('\n');
delete_tree(root);
}
输出(示例)
5 7 6 1 3 5 7 3 1 1
1 3 5 6 7
请注意,这是一个示例,它既演示了正确构建的树(因此正确的排序顺序),也消除了重复。
使这项工作的作用是将引用下降到树的实际节点指针的指针,包括在nullptr
中以main()
开头的初始根指针。 / p>
要允许重复,必须完成的只是对插入例程进行一些小的更改:
void insertElem(Node *& root, int value)
{
if (root)
{
if (value < root->value )
insertElem(root->left, value);
else // no right test, just descend
insertElem(root->right, value);
}
else
{
root = new Node(value);
}
}
仅更改示例输出如下所示:
2 9 4 2 2 4 7 2 5 6
2 2 2 2 4 4 5 6 7 9
根据需要进行调整。