插入二叉搜索树。节点更换

时间:2017-05-15 00:07:13

标签: c++ insert binary-search-tree

我使用这段代码创建一个新节点并将其插入二叉搜索树。它正确插入根,与其第一个右和左子项相同,但之后的任何内容似乎都替换了现有的子项。

例如:

     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;
}

1 个答案:

答案 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 

根据需要进行调整。