数据结构中文教材上的AVL树代码,调试过,加入了打印功能
// AVL tree implementation
#include<iostream>
using namespace std;
template <class Type>
class AVLTree{
struct AVLNode{
Type data;
AVLNode* left;
AVLNode* right;
int height;
AVLNode(const Type& element, AVLNode* l = NULL, AVLNode* r = NULL, int h = 0){
data = element;
left = l;
right = r;
height = h;
}
};
private:
AVLNode* root;
void insert(const Type& x, AVLNode* &t);
bool remove(const Type& x, AVLNode* &t);
void makeEmpty(AVLNode* &t);
int height(AVLNode* t) const { return (t == NULL)? -1: t->height; }
void LL(AVLNode* &t);
void LR(AVLNode* &t);
void RL(AVLNode* &t);
void RR(AVLNode* &t);
int max(int a, int b) { return (a > b)? a: b; }
void print(AVLNode* root, int level);
public:
AVLTree(AVLNode*t = NULL) { root = t; }
~AVLTree(){ makeEmpty(root); }
bool find(const Type& x) const;
void insert(const Type& x) { insert(x, root); }
void remove(const Type& x) { remove(x, root); }
void print(){
print(root, 0);
}
};
template <class Type>
bool AVLTree<Type>::find(const Type& x) const {
AVLNode* t = root;
while (t != NULL && t->data != x){
if (t->data > x) t = t->left;
else t = t->right;
}
if (t == NULL) return false;
else return true;
}
template <class Type>
void AVLTree<Type>::insert(const Type& x, AVLNode* &t){
if (t == NULL) t = new AVLNode(x, NULL, NULL);
else if (x < t->data){
insert(x, t->left);
if (height(t->left) - height(t->right) == 2){
if (x < t->left->data) LL(t);
else LR(t);
}
}
else {
insert(x, t->right);
if (height(t->right) - height(t->left) == 2){
if (x < t->right->data) RL(t);
else RR(t);
}
}
t->height = max(height(t->left), height(t->right)) + 1;
}
template <class Type>
void AVLTree<Type>::LL(AVLNode* &t){
AVLNode* t1 = t->left;
t->left = t1->right;
t1->right = t;
t->height = max(height(t->left), height(t->right)) + 1;
t1->height = max(height(t1->left), height(t)) + 1;
t = t1;
}
template <class Type>
void AVLTree<Type>::RR(AVLNode* &t){
AVLNode* t1 = t->right;
t->right = t1->left;
t1->left = t;
t->height = max(height(t->left), height(t->right)) + 1;
t1->height = max(height(t), height(t1->right)) + 1;
t = t1;
}
template <class Type>
void AVLTree<Type>::LR(AVLNode* &t){
RR(t->left);
LL(t);
}
template <class Type>
void AVLTree<Type>::RL(AVLNode* &t){
LL(t->right);
RR(t);
}
template <class Type>
bool AVLTree<Type>::remove(const Type& x, AVLNode* &t){
bool stop = false;
int subTree;
if (t == NULL) return true;
if (x < t->data) { stop = remove(x, t->left); subTree = 1; }
else if (x > t->data) { stop = remove(x, t->right); subTree = 2; }
else if (t->left != NULL && t->right != NULL){
AVLNode* tmp = t->right;
while(tmp->left != NULL) tmp = tmp->left;
t->data = tmp->data;
stop = remove(t->data, t->right);
subTree = 2;
}
else {
AVLNode* oldNode = t;
t = (t->left != NULL)? t->left: t->right;
delete oldNode;
return false;
}
if (stop) return true;
int bf;
switch(subTree){
case 1:
bf = height(t->left) - height(t->right) + 1;
if (bf == 0) return true;
if (bf == 1) return false;
if (bf == -1) {
int bfr = height(t->right->left) - height(t->right->right);
switch(bfr){
case 0:
RR(t); return true;
case -1:
RR(t); return false;
default: RL(t); return false;
}
}
break;
case 2:
bf = height(t->left) - height(t->right) - 1;
if (bf == 0) return true;
if (bf == -1) return false;
if (bf == 1) {
int bfl = height(t->left->left) - height(t->left->right);
switch(bfl){
case 0:
LL(t); return true;
case 1:
LL(t); return false;
default: LR(t); return false;
}
}
}
}
template <class Type>
void AVLTree<Type>::print(AVLNode* root, int level){
if (root == NULL) return;
print(root->left, level + 1);
cout << "Level " << level << ": " << root->data << endl;
print(root->right, level + 1);
}
template <class Type>
void AVLTree<Type>::makeEmpty(AVLNode* &t){
if (t == NULL) return;
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
主要的特点是在插入、删除等操作时用指针的引用做参数,以便在子树被更改时,根节点指向调整后的子树的根。AVLNode作为AVLTree的私有类,使得AVLTree可以任意使用AVLNode的成员,又保证了封装性。
利用AVL tree的思路,仿照英文教材上的bst代码另外写了一个AVL,代码见下:
// AVL tree implementation
#include<iostream>
using namespace std;
template <typename E>
class AVLNode{
private:
E it;
AVLNode* lc;
AVLNode* rc;
int height;
public:
AVLNode(const E& e, AVLNode<E>* l = NULL, AVLNode<E>* r = NULL, int h = 0){
it = e;
lc = l;
rc = r;
height = h;
}
~AVLNode(){}
E& element(){ return it; }
void setElement(const E& e){ it = e; }
inline AVLNode* left() const { return lc; }
void setLeft(AVLNode<E>* b){ lc = b; }
inline AVLNode* right() const { return rc; }
void setRight(AVLNode<E>* b){ rc = b; }
int& h(){ return height; }
};
template <typename E>
class AVL{
private:
AVLNode<E>* root;
AVLNode<E>* inserthelp(AVLNode<E>* root, const E& e);
bool findhelp(AVLNode<E>* root, const E& e) const;
void clearhelp(AVLNode<E>* root);
AVLNode<E>* removehelp(AVLNode<E>* root, const E& e);
void printhelp(AVLNode<E>*, int) const;
int max(int x, int y){ return (x > y)? x: y; }
AVLNode<E>* LL(AVLNode<E>* root);
AVLNode<E>* RR(AVLNode<E>* root);
AVLNode<E>* LR(AVLNode<E>* root);
AVLNode<E>* RL(AVLNode<E>* root);
public:
AVL(AVLNode<E>* r = NULL){ root = r; }
~AVL(){ clearhelp(root); }
void insert(const E& e){ root = inserthelp(root, e); }
bool find(const E& e) const { return findhelp(root, e); }
void remove(const E& e){ root = removehelp(root, e); }
void print() const { // Print the contents of the AVL
if (root == NULL) cout << "The AVL is empty." << endl;
else printhelp(root, 0);
}
int height(AVLNode<E>* root){
if (root == NULL) return -1;
else return root->h();
}
};
template <typename E>
void AVL<E>::clearhelp(AVLNode<E>* root){
if (root == NULL) return;
clearhelp(root->left());
clearhelp(root->right());
delete root;
}
template <typename E>
bool AVL<E>::findhelp(AVLNode<E>* root, const E& e) const {
if (root == NULL) return false;
if (e < root->element()) return findhelp(root->left());
else if (e > root->element()) return findhelp(root->right());
else return true;
}
template <typename E>
AVLNode<E>* AVL<E>::LL(AVLNode<E>* root){
AVLNode<E>* tmp = root->left();
root->setLeft(tmp->right());
tmp->setRight(root);
root->h() = max(height(root->left()), height(root->right())) + 1;
tmp->h() = max(height(tmp->left()), height(tmp->right())) + 1;
root = tmp;
return root;
}
template <typename E>
AVLNode<E>* AVL<E>::RR(AVLNode<E>* root){
AVLNode<E>* tmp = root->right();
root->setRight(tmp->left());
tmp->setLeft(root);
root->h() = max(height(root->left()), height(root->right())) + 1;
tmp->h() = max(height(tmp->left()), height(tmp->right())) + 1;
root = tmp;
return root;
}
template <typename E>
AVLNode<E>* AVL<E>::LR(AVLNode<E>* root){
root->setLeft(RR(root->left()));
root = LL(root);
return root;
}
template <typename E>
AVLNode<E>* AVL<E>::RL(AVLNode<E>* root){
root->setRight(LL(root->right()));
root = RR(root);
return root;
}
template <typename E>
AVLNode<E>* AVL<E>::inserthelp(AVLNode<E>* root, const E& e){
if (root == NULL) return new AVLNode<E>(e);
if (e < root->element()) {
root->setLeft(inserthelp(root->left(), e));
if (height(root->left()) - height(root->right()) == 2){
if (e < root->left()->element()) root = LL(root);
else root = LR(root);
}
}
else {
root->setRight(inserthelp(root->right(), e));
if (height(root->right()) - height(root->left()) == 2){
if (e < root->right()->element()) root = RL(root);
else root = RR(root);
}
}
root->h() = max(height(root->left()), height(root->right())) + 1;
return root;
}
template <typename E>
AVLNode<E>* AVL<E>::removehelp(AVLNode<E>* root, const E& e){
if (root == NULL) return NULL;
if (e < root->element()) {
root->setLeft(removehelp(root->left(), e));
if (height(root->right()) - height(root->left()) == 2){
int dif = height(root->right()->left()) - height(root->right()->right());
switch(dif){
case 0: root = RR(root); break;
case -1: root = RR(root); break;
case 1: root = RL(root); break;
}
}
}
else if (e > root->element()) {
root->setRight(removehelp(root->right(), e));
if (height(root->left()) - height(root->right()) == 2){
int dif = height(root->left()->left()) - height(root->left()->right());
switch(dif){
case 0: root = LL(root); break;
case 1: root = LL(root); break;
case -1: root = LR(root); break;
}
}
}
else {
if (root->right() == NULL){
AVLNode<E>* tmp = root;
root = root->left();
delete tmp;
}
else if (root->left() == NULL){
AVLNode<E>* tmp = root;
root = root->right();
delete tmp;
}
else {
AVLNode<E>* tmp = root->right();
while (tmp->left() != NULL) tmp = tmp->left();
root->setElement(tmp->element());
root->setRight(removehelp(root->right(), root->element()));
}
}
if (root != NULL) root->h() = max(height(root->left()), height(root->right())) + 1;
return root;
}
template <typename E>
void AVL<E>::printhelp(AVLNode<E>* root, int level) const {
if (root == NULL) return;
printhelp(root->left(), level + 1);
//for (int i = 0; i <= level; i++) cout << " ";
cout << "Level " << level << ": " << root->element() << endl;
printhelp(root->right(), level + 1);
}
可以看到,没有将AVLNode作为AVL的内嵌类或将AVL声明为AVLNode的友元,AVL对结点的调用更加不方便,不得不在AVLNode中添加element(),setElement(),left(),setLeft()……等方法,还要考虑是否有const。在调用insert(),remove()等方法时,利用inserthelp(),removehelp()返回调整后的树根的地址,例如,root = inserthelp(root, e); root->setLeft(removehelp(root->left(), e)); 。总体上,中文教材的代码更加简洁,封装性更好。