繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM