【笔记】AVL二叉平衡树

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树还挺简单的,但是自己写过之后发现没有想象中的那么容易,尤其是删除部分,开始自己写的臃肿且混乱,最后看到别的博客发现其实没必要去分四种情况。

下一篇 红黑树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值