我正在实施自己的BST和AVL树。
BSTree继承了Dictionary类。字典类是抽象的,即只提供在继承Dictionary的类中实现的纯虚函数。现在,我实现了类BSTree并在类AVL中继承它。这两个类都有root作为私有成员。 BSTree工作得很好。但是AVL中的功能是"行为不端"。
这是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);
我得到了输出:
将AVL的功能称为
Root为NULL
将AVL的功能称为
Root为NULL
将AVL的功能称为
Root为NULL
为什么root始终为NULL。正确插入数字(我使用自定义打印功能打印它们)。我想工作总是在BSTree的根变量上完成。怎么避免呢? 请帮助。
答案 0 :(得分:3)
模板类AVL
有自己的私有根:
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
是另一个成员变量,它不受这些插入使用其基类&#39; 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的根,因为显然它不是必需的。
你可以选择: