C++ 二叉搜索树插入函数

Posted

技术标签:

【中文标题】C++ 二叉搜索树插入函数【英文标题】:C++ Binary Search Tree Insertion functions 【发布时间】:2015-02-14 16:25:26 【问题描述】:

大家好,

本学期我在大学学习了几乎没有任何先验知识的 C++ 编码课程(我对指针的理解仍然有些摇摆不定)。 我必须在 C++ 中实现一个二叉搜索树,我的问题如下: 在一个带有值和指向左右节点的指针的预定义节点结构上,我应该实现几个函数,其中两个是:

void InsertNode(Node* root, Node* node)

应该将手节点适合给定的树“根”, 还有一个叫

void InsertValue(Node* root, int value)

它应该使用传递的值创建节点结构的新实例,并将其放入给定的树“根”中。为此,我应该同时使用 CreateNode(用于创建具有 int 值和左/右指针设置为 NULL 的新 Node 实例的 Node* 指针的简单函数)和 InsertNode。

我有点在跑步机上跑步,我认为我并不真正了解这些功能应该如何工作(例如它们之间的区别)。 昨天我写了这个函数:

void InsertNode(Node* root, Node* node)
    if(root == NULL)
        root = CreateNode(node->value);
    
    else if(root->value < node->value)
        if(node->left != NULL)
             InsertNode(root, node->left);
        
        else
             node->left = CreateNode(root->value);
        
    
    else if(root->value > node->value)
        if(node->right != NULL)
             InsertNode(root, node->right);
        
        else
            node->right = CreateNode(root->value);
        
    

因为如果没有后面的函数,我真的无法测试这些函数,而后面的函数实际上会用给定的节点构建树,我很好奇我是否可以在这里得到一些关于下一个函数 InsertValue 的帮助(它应该做什么而不是 InsertNode已经做了吗?:S)

提前问候和感谢。

【问题讨论】:

【参考方案1】:

初始说明:此答案假定最初调用 InsertNode 函数时,root 是树的根,node 是要插入树的节点。


这个说法有一个问题:

root = CreateNode(node->value);

由于参数root是按值传递的,也就是说是被拷贝的,赋值只会改变本地拷贝。一旦函数返回您传递给函数的原始指针就不会改变。

您需要通过引用传递指针,这意味着root 参数引用传入函数的原始变量,而不是复制它。您可以在声明参数时使用 & 符号:

Node*& root

上面的意思是root是一个指向Node的指针的引用。

所以完整的InsertNode 声明应该是这样的

void InsertNode(Node*& root, Node* node)

还有其他问题,例如这些行不正确:

if(node->left != NULL)
     InsertNode(root, node->left);

else
     node->left = CreateNode(root->value);

这是不正确的,因为node-&gt;left 应该始终是NULL,这使您使用树的root 中的值创建一个新节点,并将其分配给node-&gt;left,但您从不插入@ 987654337@ 在树中。

你应该做的只是简单

InsertNode(node->left, node);

当然你应该做同样的改变来设置正确的分支。


结合上面的两个解决方案,你的函数看起来像

void InsertNode(Node*& root, Node* node)

    if (root == 0)
        root = node;
    else if (root->value < node->value)
        InsertNode(root->left, node);
    else
        InsertNode(root->right, node);

这个函数还解决了当前代码的第三个问题:如果node-&gt;value 等于root-&gt;value 怎么办?上面的函数把它放在了正确的分支中。

【讨论】:

【参考方案2】:

当您创建一棵树时,也会为每个节点分配值。见以下代码:

typedef struct BST 
   int data;
   struct BST *lchild, *rchild;
 node;


void insert(node *root, node *new_node) 
   if (new_node->data < root->data) 
      if (root->lchild == NULL)
         root->lchild = new_node;
      else
         insert(root->lchild, new_node);
   

   if (new_node->data > root->data) 
      if (root->rchild == NULL)
         root->rchild = new_node;
      else
         insert(root->rchild, new_node);
   


node *new_node, *root;

int main()
 
        new_node = get_node();
        printf("\nEnter The Element ");
        scanf("%d", &new_node->data);

        if (root == NULL) /* Tree is not Created */
           root = new_node;
        else
           insert(root, new_node)

【讨论】:

【参考方案3】:

以下代码使用 Python 编写,用于插入 BST ::

class Node :
    def __init__(self.key):
        self.left = None
        self.right = None
        self.val = key

def insert(root.node):
    if root is None :
        root = node
    else :
        if root.val < node.val:
            if root.right is None :
                root.right = node
            else :
                insert(root.right, node)
        else :
            if root.left is None :
                root.left = node
            else :
                insert(root.left, node)

def inorder(root):
    if root :
        inorder(root.left)
        print(root.val)
        inorder(root.right)

# Driver program to test the above functions
# Let us create the following BST
#      50
#    /    \
#   30     70
#   / \    / \
#  20 40  60 80
r = Node(50)
insert(r,Node(30))
insert(r,Node(20))
insert(r,Node(40))
insert(r,Node(70))
insert(r,Node(60))
insert(r,Node(80))

# Print inoder traversal of the BST
inorder(r)

【讨论】:

以上是关于C++ 二叉搜索树插入函数的主要内容,如果未能解决你的问题,请参考以下文章

C++二叉搜索树解析

C++从青铜到王者第十九篇:C++二叉树进化之二叉搜索树

C++二叉树进阶(二叉搜索树,KV模型)

C++二叉树进阶(二叉搜索树,KV模型)

c++二叉搜索树

c++二叉搜索树