我正在实现自己的BST和AVL树。
BSTree继承了Dictionary类。字典类是抽象的,即仅提供纯虚函数以在继承字典的类中实现。现在,我实现了BSTree类,并在AVL类中继承了它。这两个类都具有root作为私有(private)成员。 BSTree完全正常。但是AVL中的put函数是“行为异常”。
这是Dictionary.hpp:

#ifndef DICTIONARY_HPP_
#define DICTIONARY_HPP_
template<class Key, class Value>
class Dictionary
{
public:
    virtual ~Dictionary(){};
    virtual void put(const Key& key, const Value& value) = 0;
};
#endif
这是BSTree.hpp:
 #ifndef BSTREE_HPP
 #define BSTREE_HPP
 #include "Dictionary.hpp"

 namespace ntl{

 template<class Key,class Value>
 class Node{
     public:
         Key key;
         Value value;
         int height;
         Node *left;
         Node *right;
         Node *parent;
         Node();
 };

 template<class Key,class Value>
 Node<Key,Value>::Node(){
     key=defaultData(key);
     value=defaultData(value);
     height=0;
     left=right=parent=NULL;
 }

template <class Key, class Value>
class BSTree : public Dictionary<Key, Value> {
private:
    Node<Key,Value> *root;
    int n;
public:
    BSTree();
    bool has(const Key& key);
    void put(const Key& key, const Value& value);
};

template<class Key,class Value>
BSTree<Key,Value>::BSTree(){
    root=NULL;
    n=0;
}

template<class Key,class Value>
bool BSTree<Key,Value>::has(const Key& key){
    //return true if key is present
    //return false if key isn't present
}

emplate<class Key, class Value>
void BSTree<Key,Value>:: put(const Key& key, const Value& value){
    Node<Key,Value> * y=NULL;
    Node<Key,Value> * x=this->root;
    while(x!=NULL){
        y=x;
        if(key<x->key){
            x=x->left;
        }else if(key>x->key){
            x=x->right;
        }else{
            break;
        }
    }
    if(x!=NULL){
        x->value=value;
    }else{
        Node<Key,Value> *newNode=new Node<Key,Value>(key,value);
        newNode->height=0;
        newNode->parent=y;
        if(y==NULL){
            root=newNode;
        }else if(newNode->key<y->key){
            y->left=newNode;
        }else{
            y->right=newNode;
        }
        n++;
        int lh,rh;
        while(newNode!=NULL){
            if(newNode->left==NULL)
                lh=-1;
            else
                lh=newNode->left->height;
            if(newNode->right==NULL)
                rh=-1;
            else
                rh=newNode->right->height;
            if(lh>rh)
                newNode->height=1+lh;
            else
                newNode->height=1+rh;
            newNode=newNode->parent;
        }
    }
}
这是AVL.hpp:
#ifndef AVL_HPP
#define AVL_HPP
#include "BSTree.hpp"

namespace ntl{

template <class Key,class Value>
class AVL : public BSTree<Key, Value> {
  private:
      Node<Key,Value> *root;
      int n;
  public:
      AVL();
      virtual void put(const Key& key, const Value& value);
};

template<class Key,class Value>
void AVL<Key,Value>::put(const Key& key, const Value& value){
  std::cout<<"Put function of AVL called\n";
  if(this->root==NULL){
    std::cout<<"Root is NULL\n";
    BSTree<Key,Value>::put(key,value);
  }else if(this->has(key)){
    BSTree<Key,Value>::put(key,value);
  }else{
    //Some More Stuff
  }
}
#endif
在main.cpp中,我做了类似的事情:
ntl::AVL<int,int> t;
t.put(50,1);
t.put(30,2);
t.put(10,3);
我正在输出:

为什么root始终为NULL。数字已正确插入(我已使用自定义打印功能将其打印出来)。我猜工作总是在BSTree的根变量上完成的。如何避免呢?
请帮忙。

最佳答案

问题
模板类AVL具有自己的私有(private)根:

    class AVL : public BSTree<Key, Value> {
    private:
         Node<Key,Value> *root;
    ...
模板类BSTree也是如此:
    class BSTree : public Dictionary<Key, Value> {
    private:
        Node<Key,Value> *root;
    ...
尽管您似乎在BSTree::root中正确更新了BSTree::put(),但AVL::root是另一个成员变量,使用其基类的BSTree::put(),这些变量不会受到这些插入的影响:
    ...
    if(this->root==NULL){
        std::cout<<"Root is NULL\n";
        BSTree<Key,Value>::put(key,value);  // if this succeeds, BSTRee's root will be non null
    ...                                     // but AVL's root is unchanged
解决方案:
摆脱AVL的根源,因为显然不需要它。
然后您可以选择:
  • 使BSTree的根受到保护,以便AVL可以访问它。
  • 或在BSTree中创建 protected (或公共(public))getter,以便AVL无需更改根即可获取根的值。
  • 关于c++ - 基类和派生类中的数据成员相同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36679226/

    10-11 03:48