【数据结构基础】平衡二叉树(AVL)

来源:互联网 发布:淘宝网天猫运动鞋 编辑:程序博客网 时间:2024/06/09 19:18

平衡二叉树理解起来很简单,但是把代码写出来,却不是一件很容易的事。

方法一:(代码参考一篇博客,现找不到地址)
主要是参照严蔚敏的数据结构c语言版,其中在插入时,引入平衡因子(balance factor)这一说法,而且在还要用一个变量taller来判断树是否真正长高。

#include <stdio.h>  #include <stdlib.h>  #define LH 1#define RH -1#define EH 0  #define TRUE  1  #define FALSE 0  typedef struct BiTNode {      int data;      int bf;        struct BiTNode *lchild, *rchild;  }BiTNode, *BiTree;   void R_Rotate( BiTree *p ) {      BiTree L;      L = (*p)->lchild;      (*p)->lchild = L->rchild;      L->rchild = *p;      *p = L;  }  void L_Rotate(BiTree *p){      BiTree R;      R=(*p)->rchild;      (*p)->rchild = R->lchild;      R->lchild = *p;      *p = R;  }  void LeftBalance( BiTree *T ){      BiTree L, Lr;      L = (*T)->lchild;      switch( L->bf ){      case 1:                 (*T)->bf = L->bf = 0;          R_Rotate( T );          break;      case -1:                Lr = L->rchild;          switch( Lr->bf ){          case 1:              (*T)->bf = -1;              L->bf = 0;              break;          case 0:              (*T)->bf = L->bf = 0;              break;          case -1:              (*T)->bf = 0;              L->bf = 1;              break;          }          Lr->bf = 0;          L_Rotate( &(*T)->lchild );         R_Rotate( T );                    }  } void RightBalance( BiTree *T ){      BiTree R, Rl;      R = (*T)->rchild;      switch( R->bf ){      case -1:           (*T)->bf = R->bf = 0;          L_Rotate( T );          break;      case 1:         Rl = R->lchild;          switch( Rl->bf ){          case 1:              (*T)->bf = 0;              R->bf = -1;              break;          case 0:              (*T)->bf = R->bf = 0;              break;          case -1:              (*T)->bf = 1;              R->bf = 0;              break;          }          Rl->bf = 0;          R_Rotate( &(*T)->rchild );         L_Rotate( T );                    }  }int InsertAVL( BiTree *T,int e,int *taller) {      if(!*T){          *T=(BiTree)malloc(sizeof(BiTNode));          (*T)->data=e;          (*T)->lchild=(*T)->rchild = NULL;          (*T)->bf = 0;          *taller = TRUE;      } else {        if(e==(*T)->data ){              *taller = FALSE;              return FALSE;          }          if(e<(*T)->data ){              if( !InsertAVL(&(*T)->lchild,e,taller)) {                  return FALSE;              }              if(*taller){                  switch((*T)->bf ){                  case 1:                                     LeftBalance( T );                      *taller = FALSE;                      break;                  case 0:                                    (*T)->bf = 1;                      *taller = TRUE;                      break;                  case -1:                                    (*T)->bf = 0;                      *taller = FALSE;                      break;                  }              }          } else{              if(!InsertAVL(&(*T)->rchild,e,taller)){                  return FALSE;              }              if( *taller ){                  switch((*T)->bf){                  case 1:                                     (*T)->bf = 0;                      *taller = FALSE;                      break;                  case 0:                                  (*T)->bf = -1;                      *taller = TRUE;                      break;                  case -1:                         RightBalance(T);                      *taller = FALSE;                      break;                  }              }          }      }      return TRUE;  }  //preorder traversal  AVLTree void Preorder_Traversal_AVL( BiTree T){    if(T){        printf("%d ",T->data);        Preorder_Traversal_AVL(T->lchild);          Preorder_Traversal_AVL(T->rchild);    }}int main(void){    int i;      int a[5]={13,24,37,90,53};     BiTree T = NULL;      int taller;      for( i=0;i<sizeof(a)/sizeof(int);i++){          InsertAVL(&T,a[i],&taller);      }     Preorder_Traversal_AVL(T);     return 0;}

方法二:这是我看浙大数据结构的MOOC提供的一种方法。直接用height表示树高,每次插入结点后,利用递归的逐层返回求树高,做相应调整,个人感觉这种方法更好。

#include<stdio.h>#include<stdlib.h>typedef struct node {    int key;    int height;    struct node *lchild, *rchild;}Node, *PNode;int Max(int a, int b) {    return a>b ? a : b;}int Get_Height(PNode R) {    return R == NULL ? 0 : R->height;}void  LL_Rotate(PNode *R) {    PNode Rl = (*R)->lchild;    (*R)->lchild = Rl->rchild;    Rl->rchild = *R;    (*R)->height = Max(Get_Height((*R)->lchild), Get_Height((*R)->rchild)) + 1;    Rl->height = Max(Get_Height(Rl->lchild), Get_Height(Rl->rchild)) + 1;    *R = Rl;}void RR_Rotate(PNode *R) {    PNode Rr = (*R)->rchild;    (*R)->rchild = Rr->lchild;    Rr->lchild = *R;    (*R)->height = Max(Get_Height((*R)->lchild), Get_Height((*R)->rchild)) + 1;    Rr->height = Max(Get_Height(Rr->lchild), Get_Height(Rr->rchild)) + 1;    *R = Rr;}void LR_Rotate(PNode *R) {    //PNode Rl = (*R)->lchild;    RR_Rotate(&(*R)->lchild);    LL_Rotate(R);}void RL_Rotate(PNode *R) {    //PNode Rr = (*R)->rchild;    LL_Rotate(&(*R)->rchild);    RR_Rotate(R);}void Insert_AVL(PNode *R, int k) {    if (!*R) {        (*R) = (PNode)malloc(sizeof(Node));        (*R)->key = k;        (*R)->height = 0;        (*R)->lchild = (*R)->rchild = NULL;    }    else {        if (k < (*R)->key) {            Insert_AVL(&(*R)->lchild, k);            if (Get_Height((*R)->lchild) - Get_Height((*R)->rchild) == 2) {                if (k < (*R)->lchild->key) {                    LL_Rotate(R);                }                else {                    LR_Rotate(R);                }            }        }        if (k > (*R)->key) {            Insert_AVL(&(*R)->rchild, k);            if (Get_Height((*R)->lchild) - Get_Height((*R)->rchild) == -2) {                if (k > (*R)->rchild->key) {                    RR_Rotate(R);                }                else {                    RL_Rotate(R);                }            }        }       }    (*R)->height = Max(Get_Height((*R)->lchild), Get_Height((*R)->rchild))+1;}void Preorder_Traversal(PNode R) {    if (R) {        printf("%d ", R->key);        Preorder_Traversal(R->lchild);        Preorder_Traversal(R->rchild);    }}int main(void) {    PNode R = NULL;    int i;    int a[16] = {3,2,1,4,5,6,7,16,15,14,13,12,11,10,8,9};//测试数据来源于网络    for (i = 0; i<sizeof(a) / sizeof(int); i++) {        Insert_AVL(&R, a[i]);    }    Preorder_Traversal(R);    return 0;}

~完

原创粉丝点击