数据结构_AVL树

来源:互联网 发布:手机自动画图软件 编辑:程序博客网 时间:2024/06/10 23:52

// 数据结构_AVL树.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

/*
在计算机科学中,AVL树是最先发明的自平衡二叉查找树。AVL树得名于它的发明者
 G.M. Adelson-Velsky 和 E.M. Landis,他们在 1962 年的论文
"An algorithm for the organization of information" 中发表了它。

AVL树的基本操作一般涉及运做同在不平衡的二叉查找树所运做的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL 旋转"。
假设由于在二叉排序树上插入结点而失去平衡的最小子树根结点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先结点),
则失去平衡后进行进行的规律可归纳为下列四种情况:
单向右旋平衡处理LL:
      由于在*a的左子树根结点的左子树上插入结点,*a的平衡因子由1增至2,致使以*a为根的子树失去平衡,则需进行一次右旋转操作;
单向左旋平衡处理RR:
      由于在*a的右子树根结点的右子树上插入结点,*a的平衡因子由-1变为-2,致使以*a为根的子树失去平衡,则需进行一次左旋转操作;
双向旋转(先左后右)平衡处理LR:
      由于在*a的左子树根结点的右子树上插入结点,*a的平衡因子由1增至2,致使以*a为根的子树失去平衡,则需进行两次旋转(先左旋后右旋)操作。
双向旋转(先右后左)平衡处理RL:
      由于在*a的右子树根结点的左子树上插入结点,*a的平衡因子由-1变为-2,致使以*a为根的子树失去平衡,则需进行两次旋转(先右旋后左旋)操作。
*/
/*
typedef struct AVLTREE{

 AVLTREE *p;
 AVLTREE *left;
 AVLTREE *right;
 int  key;
 int  high;
}AVLTREE,*PAVLTREE;

PAVLTREE root = NULL;

 

int avl_insert(AVLTREE *z){

 PAVLTREE x = NULL,y = NULL;

 x = root;

 while(x != NULL){

  y = x;

  if(z->key > x->key){

   x->high--;

   
   x = x->right;
  
  }
  else{
   
   x->high++;
   x = x->left;
  
  }
  
 }

 z->p = y;

 if( y == NULL){

  root = z;
 }
 else{

  if(z->key > y->key){

   y->right = z;
  }
  else{

   y->left = z;
  }
 }

 return 0;

}


int main(int argc, char* argv[])
{

 int a[] = {7,2,5,4,9,10,3,15,18};

 int i = 0;

 for(i = 0; i < 9;i++){

  PAVLTREE ptreenode = (PAVLTREE)malloc(sizeof(PAVLTREE));

  ptreenode->high = 0;

  ptreenode->key = a[i];

  ptreenode->left = NULL;

  ptreenode->right = NULL;

  ptreenode->p = NULL;

  avl_insert(ptreenode);

 }

 return 0;
}
*/

/*数据结构书中的实现*/


#define LH 1
#define EH 0
#define RH -1

typedef struct BSTNode{

 int data;
 int bf;
 BSTNode *lchild;
 BSTNode *rchild;

}BSTNode,*BSTree;

void R_Rotate(BSTree &p){
 
 BSTree lc = NULL;
 lc = p->lchild;
 p->lchild = lc->rchild;
 lc->rchild = p;
 p = lc;
}

void L_Rotate(BSTree &p){

 BSTree rc = NULL;
 rc = p->rchild;
 p->rchild = rc->lchild;
 rc->lchild = p;
 p = rc;
}

void leftBalance(BSTree &T){

 BSTree lc = NULL;

 BSTree rd = NULL;

 lc = T->lchild;

 switch(lc->bf){

  case LH:
  
   T->bf = lc->bf = EH;
   R_Rotate(T);
   break;

  case RH:
   rd = lc->rchild;
   switch(rd->bf){

    case LH:
     T->bf = RH;
     lc->bf = EH;
     break;
    case EH:
     T->bf = lc->bf = EH;
     break;
    case RH:
     T->bf = EH;
     lc->bf =LH;
     break;

   }
   rd->bf = EH;
   L_Rotate(T->lchild);
   R_Rotate(T);
 }
}


void RightBalance(BSTree &T){
 
 BSTree lc = NULL;
 
 BSTree rd = NULL;
 
 lc = T->rchild;
 
 switch(lc->bf){
  
 case RH:
  
  T->bf = lc->bf = EH;
  L_Rotate(T);
  break;
  
 case LH:
  rd = lc->lchild;
  switch(rd->bf){
   
  case LH:
   T->bf = LH;
   lc->bf = EH;
   break;
  case EH:
   T->bf = lc->bf = EH;
   break;
  case RH:
   T->bf = EH;
   lc->bf =RH;
   break;
   
  }
  rd->bf = EH;
  R_Rotate(T->rchild);
  L_Rotate(T);
 }
}

 

BSTree insertAVL(BSTree &T,int e,boolean &taller){

 if(!T){
  T = (BSTree)malloc(sizeof(BSTNode));
  T->data = e;
  T->lchild=T->rchild = NULL;
  T->bf = EH;
  taller = TRUE;
 }
 else{

  if(e == T->data){

   taller = false;
   return 0;
  }
  if(e < T->data){

   if(!insertAVL(T->lchild,e,taller)){

    if(taller){

     switch(T->bf){
      
     case LH:
      leftBalance(T);
      taller = FALSE;
      break;
     case EH:
      T->bf = LH;
      taller = TRUE;
      break;
     case RH:
      T->bf = EH;
      taller = FALSE;
      break;

     }
    }
   }
  }
  else{
   if(!insertAVL(T->rchild,e,taller)){

    if(taller){
     
     switch(T->bf){
      
     case LH:
      T->bf = EH;
      taller = FALSE;
      break;
     case EH:
      T->bf = RH;
      taller = TRUE;
      break;
     case RH:
      RightBalance(T);
      taller = FALSE;
      break;
      
     }
    }

   }
  }
 }

 return 0;

}

boolean bol = FALSE;

int main(int argc, char* argv[])
{

 int i = 0;

 BSTree bstree = NULL,breturn = NULL;

 for(i = 0; i < 10; i++){

  insertAVL(bstree,i,bol);

 }


 return 0;
}