我正在实现自己的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的根源,因为显然不需要它。
然后您可以选择:
关于c++ - 基类和派生类中的数据成员相同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36679226/