博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
平衡二叉树
阅读量:5278 次
发布时间:2019-06-14

本文共 4327 字,大约阅读时间需要 14 分钟。

平衡二叉树又称AVL树。它或者是颗空树,或者是具有下列性质的二叉树:它的左子树和右子树都是平衡二叉树,且左子树和右子树的深度之差的绝对值不超过1。若将二叉树节点的平衡因子BF定义为该节点的左子树的深度减去它的右子树的深度,则平衡二叉树上全部节点的平衡因子仅仅可能为-1,0,1.仅仅要二叉树上有一个节点的平衡因子的绝对值大于1,那么这颗平衡二叉树就失去了平衡。

如果我们已经有棵平衡二叉树,如今让我们来看看插入节点后,原来节点失去平衡后,我们进行选择的处理方式。

平衡二叉树多用于查找数据,所以平衡二叉树又是颗二叉排序树。

那么怎样创建一颗平衡二叉树呢?

创建平衡二叉树,我们採用依次插入节点的方式进行。而平衡二叉树上插入节点採用递归的方式进行。递归算法例如以下:

(1)      若该树为一空树,那么插入一个数据元素为e的新节点作为平衡二叉树的根节点,树的高度添加1。

(2)      若待插入的数据元素e和平衡二叉树(BBST)的根节点的keyword相等,那么就不须要进行插入操作。

(3)      若待插入的元素e比平衡二叉树(BBST)的根节点的keyword小,并且在BBST的左子树中也不存在和e有同样keyword的节点,则将e插入在BBST的左子树上,并且当插入之后的左子树深度添加1时,分别就下列情况处理之。

(a)    BBST的根节点的平衡因子为-1(右子树的深度大于左子树的深度):则将根节点的平衡因子更改为0,BBST的深度不变;

(b)    BBST的根节点的平衡因子为0(左右子树的深度相等):则将根节点的平衡因子改动为1,BBST的深度添加1;

(c)    BBST的根节点的平衡因子为1(左子树的深度大于右子树的深度):若BBST的左子树根节点的平衡因子为1,则须要进行单向右旋转平衡处理,而且在右旋处理后,将根节点和其右子树根节点的平衡因子更改为0,树的深度不变;

若BBST的左子树根节点的平衡因子为-1,则需进行先向左,后向右的双向旋转平衡处理,而且在旋转处理之后,改动根节点和其左,右子树根节点的平衡因子,树的深度不变;

(4)      若e的keyword大于BBST的根节点的keyword,并且在BBST的右子树中不存在和e有同样keyword的节点,则将e插入到BBST的右子树上,并且当插入之后的右子树深度加1时,分别就不同的情况处理之。

(a)      BBST的根节点的平衡因子是1(左子树的深度大于右子树的深度):则将根节点的平衡因子改动为0,BBST的深度不变;

(b)      BBST的根节点的平衡因子是0(左右子树的深度相等):则将根节点的平衡因子改动为-1,树的深度加1;

(c)      BBST的根节点的平衡因子为-1(右子树的深度大于左子树的深度):若BBST的右子树根节点的平衡因子为1,则须要进行两次选择,第一次先向右旋转,再向左旋转处理,而且在旋转处理之后,改动根节点和其左,右子树根节点的平衡因子,树的深度不变;

若BBST的右子树根节点的平衡因子为1,则须要进行一次向左的旋转处理,而且在左旋之后,更新根节点和其左,右子树根节点的平衡因子,树的深度不变;

以下附上本人的代码:

#include 
#include
/************************************************************************//* 平衡二叉树---AVL *//************************************************************************/#define LH +1#define EH 0#define RH -1typedef int ElemType;typedef struct BSTNode{ ElemType data; int bf;//balance flag struct BSTNode *lchild,*rchild;}*PBSTree;void R_Rotate(PBSTree* p){ PBSTree lc = (*p)->lchild; (*p)->lchild = lc->rchild; lc->rchild = *p; *p = lc;}void L_Rotate(PBSTree* p){ PBSTree rc = (*p)->rchild; (*p)->rchild = rc->lchild; rc->lchild = *p; *p = rc;}void LeftBalance(PBSTree* T){ PBSTree lc,rd; 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); break; }}void RightBalance(PBSTree* T){ PBSTree lc,rd; 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 = EH; lc->bf = RH; break; case EH: (*T)->bf = lc->bf = EH; break; case RH: (*T)->bf = EH; lc->bf = LH; break; } rd->bf = EH; R_Rotate(&(*T)->rchild); L_Rotate(T); break; }}int InsertAVL(PBSTree* T,ElemType e,bool* taller){ if ((*T)==NULL) { (*T)=(PBSTree)malloc(sizeof(BSTNode)); (*T)->bf = EH; (*T)->data = e; (*T)->lchild = NULL; (*T)->rchild = NULL; } else if (e == (*T)->data) { *taller = false; return 0; } else if (e < (*T)->data) { if(!InsertAVL(&(*T)->lchild,e,taller)) return 0; 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)) return 0; 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 1;}bool FindNode(PBSTree root,ElemType e,PBSTree* pos){ PBSTree pt = root; (*pos) = NULL; while(pt) { if (pt->data == e) { //找到节点,pos指向该节点并返回true (*pos) = pt; return true; } else if (pt->data>e) { pt = pt->lchild; } else pt = pt->rchild; } return false;}void InorderTra(PBSTree root){ if(root->lchild) InorderTra(root->lchild); printf("%d ",root->data); if(root->rchild) InorderTra(root->rchild);}int main(){ int i,nArr[] = {1,23,45,34,98,9,4,35,23}; PBSTree root=NULL,pos; bool taller; for (i=0;i<9;i++) { InsertAVL(&root,nArr[i],&taller); } InorderTra(root); if(FindNode(root,103,&pos)) printf("\n%d\n",pos->data); else printf("\nNot find this Node\n"); return 0;}

转载于:https://www.cnblogs.com/zfyouxi/p/4007057.html

你可能感兴趣的文章
Bootstrap--响应式导航条布局
查看>>
Learning Python 009 dict(字典)和 set
查看>>
JavaScript中随着鼠标拖拽而移动的块
查看>>
HDU 1021 一道水题
查看>>
The operation couldn’t be completed. (LaunchServicesError error 0.)
查看>>
php每天一题:strlen()与mb_strlen()的作用分别是什么
查看>>
工作中收集JSCRIPT代码之(下拉框篇)
查看>>
《转载》POI导出excel日期格式
查看>>
code异常处理
查看>>
git - 搭建最简单的git server
查看>>
会话控制
查看>>
推荐一款UI设计软件Balsamiq Mockups
查看>>
Linux crontab 命令格式与详细例子
查看>>
百度地图Api进阶教程-地图鼠标左右键操作实例和鼠标样式6.html
查看>>
游标使用
查看>>
LLBL Gen Pro 设计器使用指南
查看>>
SetCapture() & ReleaseCapture() 捕获窗口外的【松开左键事件】: WM_LBUTTONUP
查看>>
Android 设置界面的圆角选项
查看>>
百度地图api服务端根据经纬度得到地址
查看>>
CSS中隐藏内容的3种方法及属性值
查看>>