您的位置:首页 > 其它

DataStructure-8.2-平衡二叉树

2015-08-27 23:44 148 查看
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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: