DataStructure-8.2-平衡二叉树

来源:互联网 发布:尘埃3知乎 编辑:程序博客网 时间:2024/05/17 04:30

8.2 平衡二叉树

   平衡二叉树或者是一棵空的二叉排序树,或者是具有下列性质的二叉排序树:

   (1) 根结点的左子树和右子树的深度最多相差1.

   (2)根结点的左子树和右子树也都是平衡二叉树.


8.3 平衡二叉树的实现

BalanceBiTree.h

#ifndef BALANCEBITREE_H
#define BALANCEBITREE_H

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

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

typedef int DataType;

typedef struct BiTNode
{
    DataType data; //结点数据
    int BF;        //结点的平衡因子
    struct BiTNode *lchild,*rchild; //左右孩子指针
}BiNode,*BiTree;

void CreateBalanceBiTree(BiTree *bt,DataType r[],int n);
void R_Rotate(BiTree *p);  //以p为根结点的二叉排序树进行右旋转
void L_Rotate(BiTree *p);  //以p为根结点的二叉排序树进行左旋转
void LeftBalance(BiTree *bt); //左子树调整
void RightBalance(BiTree *bt); //右子树调整
bool InsertAVL(BiTree *bt,DataType e,bool *taller); //插入
BiNode* SearchBST(BiTree *bt,DataType e);

void InOrder(BiTree *bt);

#endif


BalanceBiTree.c

#include "BalanceBiTree.h"

/*初始化平衡二叉树,并构建平衡二叉树*/
void CreateBalanceBiTree(BiTree *bt,DataType r[],int n)
{
    (*bt) = (BiTree)malloc(sizeof(BiNode));
    (*bt) = NULL;
    int i;
    bool taller;
    for(i=0;i<n;i++)
    {
        InsertAVL(bt,r[i],&taller);
    }
}

/*以p为根结点的二叉排序树进行右旋转*/
void R_Rotate(BiTree *p)
{
    BiNode *L;
    L = (*p)->lchild;
    (*p)->lchild = L->rchild;
    L->rchild = (*p);
    (*p) = L;
}

/*以p为根结点的二叉排序树进行左旋转*/
void L_Rotate(BiTree *p)
{
    BiNode *R;
    R = (*p)->rchild;
    (*p)->rchild = R->lchild;
    R->lchild = (*p);
    (*p) = R;
}
void LeftBalance(BiTree *bt)
{
    BiNode *L,*Lr;
    L = (*bt)->lchild;
    switch(L->BF)
    {
        /*检查bt的左子树平衡度,并做相应的平衡处理*/
        case LH:    /*新结点插入在bt的左孩子的左子树上,做单右旋转处理*/
             (*bt)->BF = L->BF = EH;
             R_Rotate(bt);
             break;
        case RH:    /*新结点插入在bt的左孩子的右子树上,做双旋转处理*/
             Lr = L->rchild;
             switch(Lr->BF)
             {
                 case LH:
                      (*bt)->BF = RH;
                      L->BF = EH;
                      break;
                 case EH:
                      (*bt)->BF = L->BF = EH;
                      break;
                 case RH:
                      (*bt)->BF = EH;
                      L->BF = LH;
                      break;
             }
             Lr->BF = EH;
             L_Rotate(&(*bt)->lchild);
             R_Rotate(bt);
    }
}

void RightBalance(BiTree *bt)
{
    BiNode *R,*Rr;
    R = (*bt)->rchild;
    switch(R->BF)
    {
        /*检查bt的右子树平衡度,并做相应的平衡处理*/
        case RH:    /*新结点插入在bt的右孩子的右子树上,做单左旋转处理*/
             (*bt)->BF = R->BF = EH;
             L_Rotate(bt);
             break;
        case LH:    /*新结点插入在bt的右孩子的左子树上,做双旋转处理*/
             Rr = R->rchild;
             switch(Rr->BF)
             {
                 case LH:
                      (*bt)->BF = EH;
                      R->BF = RH;
                      break;
                 case EH:
                      (*bt)->BF = R->BF = EH;
                      break;
                 case RH:
                      (*bt)->BF = LH;
                      R->BF = EH;
                      break;
             }
             Rr->BF = EH;
             R_Rotate(&(*bt)->rchild);
             L_Rotate(bt);
    }
}

/*若在平衡的二叉排序树bt中不存在和e有相同关键字的结点,则插入一个
 * 数据元素e的新结点并返回1,否则返回0。若因插入而使二叉排序树
 * 失去平衡,则作平衡旋转处理,taller反映bt长高与否。*/
bool InsertAVL(BiTree *bt,DataType e,bool *taller)
{
    if((*bt) == NULL)
    {
        (*bt) = (BiTree)malloc(sizeof(BiNode));
        (*bt)->data = e;
        (*bt)->lchild = (*bt)->rchild = NULL;
        (*bt)->BF = EH;
        *taller = true;
    }
    else
    {
        if(e == (*bt)->data) //相等,不插入
        {
            *taller = false;
            return false;
        }
        if(e<(*bt)->data)
        {
            if(InsertAVL(&(*bt)->lchild,e,taller)==false) //未插入
            {
                return false;
            }
            if(*taller == true)
            {
                switch((*bt)->BF)
                {
                    case LH:  //原本左子树比右子树高,需要做左平衡处理
                         LeftBalance(bt);
                         *taller = false;
                         break;
                    case EH:  //原本左右子树等高,现因左子树增高而树增高
                         (*bt)->BF = LH;
                         *taller = true;
                         break;
                    case RH:  //原本右子树比左子树高,现在左右子树等高
                         (*bt)->BF = EH;
                         *taller = false;
                         break;
                }
            }
        }
        else   //在bt的右子树中搜寻
        {
            if(InsertAVL(&(*bt)->rchild,e,taller) == false)
            {
                return false;
            }
            if(*taller==true) //插入右子树,且右子树长高
            {
                switch((*bt)->BF)
                {
                    case LH:  //原本左子树比右子树高,现在左右子树等高
                         (*bt)->BF = EH;
                         *taller = false;
                         break;
                    case EH:  //原本左右子树等高,现在右子树变高
                         (*bt)->BF = RH;
                         *taller = true;
                         break;
                    case RH:  //原本右子树比左子树高,现在需做右平衡处理
                         RightBalance(bt);
                         *taller = false;
                         break;

                }
            }
        }
    }
    return true;
}

BiNode* SearchBST(BiTree *bt,DataType e)
{
    /*若*bt为空树,则查找失败*/
    if(*bt == NULL)
    {
        return NULL;
    }
    /*否则,如果e等于(*bt)->data,则查找成功*/
    else if((*bt)->data == e)
    {
        return *bt;
    }
    /*否则,如果e<(*bt)->data,则继续查找(*bt)的左子树*/
    else if((*bt)->data > e){
        return SearchBST(&(*bt)->lchild,e);
    }
    /*否则,如果e>(*bt)->data,则继续查找(*bt)的右子树*/
    else{
        return SearchBST(&(*bt)->rchild,e);
    }

}
void InOrder(BiTree *bt)
{
    if(*bt == NULL)
    {
        return ;
    }
    else{

        InOrder(&(*bt)->lchild);
        printf("%d\n",(*bt)->data);
        InOrder(&(*bt)->rchild);
    }
}


main.c

#include "BalanceBiTree.h"

int main(void)
{
    int i;
    int r[8] = {10,15,23,5,7,14,25,30};
    BiTree B = NULL;

    CreateBalanceBiTree(&B,r,8);

    InOrder(&B);
    printf("Search 7 :\n",SearchBST(&B,7));

    return 0;
}












0 0