code
#include <iostream>
#include <stdio.h>
#include <cstdlib>
using namespace std;
template<typename T>
class AvlNode{
public:
T data;
int height;
AvlNode *l;
AvlNode *r;
};
template<typename T>
class AvlTree: public AvlNode<T>{
public:
AvlTree();
~AvlTree();
AvlNode<T> *root;
AvlNode<T> *find(T data);
void add(T data);
int getheight(AvlNode<T> *root);
void remove(T data);
private:
AvlNode<T> *find(T data, AvlNode<T> *root);
void add(T data, AvlNode<T> *&root);
void remove(T data, AvlNode<T> *&root);
AvlNode<T> *LL(AvlNode<T> *&t);
AvlNode<T> *RR(AvlNode<T> *&t);
AvlNode<T> *LR(AvlNode<T> *&t);
AvlNode<T> *RL(AvlNode<T> *&t);
void finddelete(AvlNode<T> *root);
AvlNode<T> *findmax(AvlNode<T> *&t);
AvlNode<T> *findmin(AvlNode<T> *&t);
};
template<typename T>
AvlNode<T> *AvlTree<T>::findmax(AvlNode<T> *&root){
if( root == NULL){
return NULL;
}
if(root->r == NULL){
return root;
}
return findmax(root->r);
}
template<typename T>
AvlNode<T> *AvlTree<T>::findmin(AvlNode<T> *&root){
if( root == NULL){
return NULL;
}
if(root->l == NULL){
return root;
}
return findmax(root->l);
}
template<typename T>
void AvlTree<T>::remove(T data){
if(root == NULL){
return ;
}
if(root ->data > data){
remove(data, root -> l);
if(getheight(root ->l)-getheight(root ->r)>1){
if(getheight(root ->r->l)>getheight(root ->r->r)){
root = RL(root);
}else{
root = RR(root);
}
}else{
root ->height = max(getheight(root ->l), getheight(root ->r))+1;
}
}
if(root ->data < data){
remove(data, root -> r);
if(getheight(root ->r)-getheight(root ->l)>1){
if(getheight(root ->l->r)>getheight(root ->l->l)){
root = LR(root);
}else{
root = LL(root);
}
}else{
root ->height = max(getheight(root ->l), getheight(root ->r))+1;
}
}
if(root -> data == data){
if(root -> l != NULL && root -> r != NULL){
if(getheight(root -> l)> getheight(root -> r)){
root->data = findmax(root ->l) ->data;
remove(root -> data, root->l);
}else{
root->data = findmin(root->r)->data;
remove(root->data, root->r);
}
}else{
AvlNode<T> *old = root;
root = root->l ? root->l: root->r;
delete old;
}
}
}
template<typename T>
void AvlTree<T>::remove(T data, AvlNode<T> *&root){
if(root == NULL){
return ;
}
if(root ->data > data){
remove(data, root -> l);
}
if(root ->data < data){
remove(data, root -> r);
}
if(root -> data == data){
if(root -> l != NULL && root -> r != NULL){
if(getheight(root -> l)> getheight(root -> r)){
root->data = findmax(root ->l)->data;
remove(root -> data, root->l);
}else{
root->data = findmin(root->r)->data;
remove(root->data, root->r);
}
}else{
AvlNode<T> *old = root;
root = root->l ? root->l: root->r;
delete old;
}
}
}
template<typename T>
AvlTree<T>::AvlTree(){
this->root = NULL;
}
template<typename T>
AvlTree<T>::~AvlTree(){
if(root == NULL) return ;
finddelete(this->root -> l);
finddelete(this->root -> r);
delete this->root;
}
template<typename T>
void AvlTree<T>::finddelete(AvlNode<T> *root){
if(root == NULL) return ;
finddelete(root -> l);
finddelete(root -> r);
delete root;
}
template<typename T>
AvlNode<T> *AvlTree<T>::LL(AvlNode<T> *&t){
AvlNode<T> *q = t -> l;
t -> l = q -> r;
q -> r = t;
t = q;
t->height = max(getheight(t->l), getheight(t->r))+1;
q->height = max(getheight(q->l), getheight(q->r))+1;
return q;
}
template<typename T>
AvlNode<T> *AvlTree<T>::RR(AvlNode<T> *&t){
AvlNode<T> *q = t -> r;
t -> r = q -> l;
q -> l = t;
t = q;
t->height = max(getheight(t->l), getheight(t->r))+1;
q->height = max(getheight(q->l), getheight(q->r))+1;
return q;
}
template<typename T>
AvlNode<T> *AvlTree<T>::LR(AvlNode<T> *&t){
RR(t->l);
return LL(t);
}
template<typename T>
AvlNode<T> *AvlTree<T>::RL(AvlNode<T> *&t){
LL(t->l);
return RR(t);
}
template<typename T>
int AvlTree<T>::getheight(AvlNode<T> *root){
if(root == NULL){
return -1;
}
return root -> height;
}
template<typename T>
AvlNode<T>* AvlTree<T>::find(T data){
if(this->root == NULL){
return NULL;
}
if(this->root->data > data){
return find(data, this->root->l);
}
if(this->root->data < data){
return find(data, this->root->r);
}
if(this->root->data == data){
return this->root;
}
return NULL;
}
template<typename T>
AvlNode<T>* AvlTree<T>::find(T data, AvlNode<T> *root){
if(root == NULL){
return NULL;
}
if(root->data > data){
return find(data, root->l);
}
if(root->data < data){
return find(data, root->r);
}
if(root->data == data){
return root;
}
return NULL;
}
template<typename T>
void AvlTree<T>::add(T data){
if(this->root == NULL){
this->root = new AvlNode<T>;
this->root->data = data;
this->root->l = this->root->r = NULL;
}
if(this->root->data > data){
add(data, this->root->l);
if(abs(getheight(this->root->l)-getheight(this->root->r))>1){
if(data < this->root->l->data){
this->root=LL(this->root);
}else {
this->root=RR(this->root);
}
}
}
if(this->root->data < data){
add(data, this->root->r);
if(abs(getheight(this->root->l)-getheight(this->root->r))>1){
if(data > this->root->r->data){
this->root=RR(this->root);
}else {
this->root=LL(this->root);
}
}
}
this->root ->height = max(getheight(this->root->l), getheight(this->root->r))+1;
}
template<typename T>
void AvlTree<T>::add(T data, AvlNode<T> *&root){
if(root == NULL){
root = new AvlNode<T>;
root -> data = data;
root -> l = root -> r = NULL;
}
if(root->data > data){
add(data, root->l);
if(abs(getheight(root->l)-getheight(root->r))>1){
if(data < root->l->data){
root=LL(root);
}else {
root=RR(root);
}
}
}
if(root->data < data){
add(data, root->r);
if(abs(getheight(root->l)-getheight(root->r))>1){
if(data > root->r->data){
root=RR(root);
}else {
root=LL(root);
}
}
}
root ->height = max(getheight(root->l), getheight(root->r))+1;
}
int main(){
int n=100;
AvlTree<int> *tree = new AvlTree<int>;
for(int i=0;i <n; i++){
tree->add(i);
}
for(int i=0;i<50;i++){
tree->remove(i);
}
int a=88;
tree->remove(a);
for(int i=0;i<n;i++){
AvlNode<int> *a = tree->find(i);
if( a!= NULL){
cout<<i;
if(a->l != NULL)
cout<<" l "<<a->l->data;
else
cout<<" l NULL";
if(a->r != NULL)
cout<<" r "<<a->r->data;
else
cout<<" r NULL";
cout<<" "<<a->height<<endl;
}
}
for(int i=0;i<n;i++){
AvlNode<int> *a = tree->find(i);
if( a!= NULL){
}else{
cout<<"remove "<<i<<endl;
}
}
return 0;
}
心得
之前觉得AVL树还挺简单的,但是自己写过之后发现没有想象中的那么容易,尤其是删除部分,开始自己写的臃肿且混乱,最后看到别的博客发现其实没必要去分四种情况。
下一篇 红黑树