向二叉搜索树添加节点

Add node to binary search tree

本文关键字:添加 节点 搜索树      更新时间:2023-10-16

下面的代码应该在我的BST结构中添加一个节点,但是没有这样做。新节点不附加到树中,包括根节点。谁能指出问题在哪里?

树的构造函数:

template <typename K, typename T>
MyBinaryTree<K, T>::MyBinaryTree() {
    root = nullptr;
}

从外部调用的函数:

    template <typename K, typename T>
void MyBinaryTree<K, T>::addValue(K key, T value) {
    Node *node = new Node(key, value);
    addToSubtree(root, node);
}

和必须连接节点的内部私有函数:

    template <typename K, typename T>
void MyBinaryTree<K, T>::addToSubtree(MyBinaryTree<K, T>::Node *node,
            MyBinaryTree<K, T>::Node *toAdd) {
    if(node == nullptr) {
        node = toAdd;
    } else {
        if(toAdd->key > node->key) addToSubtree(node->right, toAdd);
        else if(toAdd->key < node->key) addToSubtree(node->left, toAdd);
    }
}

您应该使用引用,如:MyBinaryTree<K, T>::Node *&root

因为当你在addToSubtree中修改root时,它只修改本地函数参数root,根参数的副本,而不是根参数本身。

你的node变量是一个局部变量,包含指向Node的指针,当你给它赋值时,它只适用于函数范围内的局部变量。

要使您的函数工作,您应该使node变量指针指向指针(因此它被称为addToSubtree(&node->right, toAdd)或指针引用)。

你的代码有两个问题:

  1. 虽然它应该代表面向对象的思想,但代码又回到了c风格。root元素不应该作为参数传递。它自动存在于每个成员函数作用域中,因为它是一个成员变量。

this:

   template <typename K, typename T>
void MyBinaryTree<K, T>::addToSubtree(MyBinaryTree<K, T>::Node *root,
            MyBinaryTree<K, T>::Node *toAdd) {
   //rest...
}

应该是这样的:

   template <typename K, typename T>
void MyBinaryTree<K, T>::addToSubtree( MyBinaryTree<K, T>::Node *toAdd) {
    if(root == nullptr) {
        root = toAdd;
    } //rest...
}

函数已经知道root是什么,因为root是成员变量。成员函数可以更改成员变量,而不需要将它们传递给函数

真正的问题是指针指针到指针之间的差异。当我们想要一个函数改变给定的参数之一时,该参数应该作为指针或引用传递。

如果实参已经是一个指针,为了改变指针本身,它应该作为指针对指针或指针对

的引用传递。所以,让我们假设我们想继续传递root作为一个参数(我们不),我们应该传递它作为
void MyBinaryTree<K, T>::addToSubtree(MyBinaryTree<K, T>::Node **root,
            MyBinaryTree<K, T>::Node *toAdd) {
    if(*root == nullptr) {
        *root = toAdd;
        //rest

作为

void MyBinaryTree<K, T>::addToSubtree(MyBinaryTree<K, T>::Node*& root,
            MyBinaryTree<K, T>::Node *toAdd) {
    if(root == nullptr) {
        root = toAdd;
       //the rest...

第二个更像c++风格,第一个更像C风格,但两者都是有效的