[英]Insert into binary search tree. Nodes replacing
我使用这段代码来创建一个新节点并将其插入到二进制搜索树中。 它会正确插入根,与第一个左右子节点相同,但是之后的所有内容似乎都将替换现有子节点。
例如:
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;
}
您的左,右decension逻辑不应该盲目地覆盖root->left
和/或root->right
。 在您知道要插入树中之前,也不应分配新节点。 最后,引用点(或指向指针的指针,但毕竟是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
请注意,这个示例既演示了正确构建的树(因此具有正确的排序顺序),又消除了重复项。
使这项工作有效的原因是,这些指针作为对树的实际节点指针的引用而下降,包括在main()
以nullptr
开头的初始根指针。
为了允许重复,所有要做的就是对插入例程进行一些小的更改:
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
适应需要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.