【问题标题】:Tree class root node not updating树类根节点未更新
【发布时间】:2015-07-29 03:25:13
【问题描述】:

我正在尝试用 C++ 编写一个 AVL 树类,我只是从编写普通 BST 的代码开始,但我遇到了一个问题。我遇到的问题是我的插入功能。我尝试将元素插入到树中,但实际上并没有这样做。我不太确定它为什么不这样做,我的直觉是我正在从函数中更改树,但我没有做任何事情来保存这些更改,我不知道该怎么做那个。

#ifndef AVLTREE_H
#define AVLTREE_H
#include <iostream>

template <class K, class V>
struct AVLNode{
    K Key;
    V Value;
    AVLNode<K,V> *left;
    AVLNode<K,V> *right;
};

template <class K, class V>
class AVLTree{
    public:
        AVLTree();
        ~AVLTree();
        void insert(const K& Key, const V& Value);
        void print_AVL();
    private:
        void print_AVL2(AVLNode<K,V> *node);
        void insert2(AVLNode<K,V> *node, const K& Key, const V& Value);
        AVLNode<K,V> *root;
};

template <class K, class V>
AVLTree<K,V>::AVLTree(){
    root = nullptr;
}

template <class K, class V>
AVLTree<K,V>::~AVLTree(){
    delete root;
}
template <class K, class V>
void AVLTree<K,V>::insert(const K& Key, const V& Value){
    std::cout << "Trying to insert " << Key << ", " << Value << std::endl;
    insert2(root, Key, Value);
}

template <class K, class V>
void AVLTree<K,V>::insert2(AVLNode<K,V> *n, const K& Key, const V& Value){
    std::cout << n << std::endl;
    if(n== nullptr){
        n = new AVLNode<K,V>;
        n->Key = Key;
        n->Value = Value;
        n->parent = nullptr;
        n->left = nullptr;
        n->right = nullptr;
    }
    else if(n->Key > Key){
        insert2(n->left, Key, Value);
    }
    else{
        insert2(n->right, Key, Value);
    }
    std::cout << n << std::endl;
}

template <class K, class V>
void AVLTree<K,V>::print_AVL(){
    print_AVL2(root);
}


template <class K, class V>
void AVLTree<K,V>::print_AVL2(AVLNode<K,V> *n){
    std::cout << n << std::endl;
    if(n == nullptr){
        return;
    }
    print_AVL2(n->left);
    std::cout << "Name, ID: " << n->Value << ", " << n->Key << std::endl;
    print_AVL2(n->right);
}


#endif

我的 Main 函数如下所示:

#include "AVLTree.hpp"
#include <iostream>

int main() 
{
    AVLTree<std::string,std::string> Tree;
    Tree.insert("Hello","World");
    Tree.print_AVL();
    return 0;
}

【问题讨论】:

  • n = new AVLNode&lt;K,V&gt;; 不会做调用者期望的事情,除非你通过引用传递n(如引用指针)。现在它是内存泄漏的秘诀。
  • parent 中的insert2() 是什么?
  • 我希望树中的每个节点都有一个父指针,指向它所属的节点
  • @OmarMorales 然后可能在AVLNode 中声明它,而不是保持原样,这会导致未知成员编译时错误。无论如何,我之前的评论是有效的。

标签: c++ class binary-search-tree avl-tree root-node


【解决方案1】:

请记住,即使在 C++ 中,除非明确告知,否则参数是按值传递因此:

void AVLTree<K,V>::insert2(AVLNode<K,V> *n, const K& Key, const V& Value)

加上这个:

n = new AVLNode<K,V>;

只会将new 调用的结果分配给自动变量n,该变量将在此函数返回时消失。

如果要保留该结果,请通过引用传递指针:

void AVLTree<K,V>::insert2(AVLNode<K,V>*& n, const K& Key, const V& Value)
// reference to the caller's pointer ===^

在 decl 和实现中都发生了变化。剩下的 parent 指针未声明成员我留给您修复,以及在您开始向树中添加更多节点后,根节点的未销毁子节点导致的内存泄漏。

【讨论】:

  • 我发现新手在使用基本类型时理解按值传递,但在使用指针时忘记了它。当然,如果您想更改指向的内容,那么按值传递不是问题,但是当您想更改指针本身(如 OP)时,则需要按引用传递。
猜你喜欢
  • 2022-01-08
  • 2019-10-29
  • 2019-09-20
  • 2021-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多