C++代码,数据结构-平衡二叉树
来源:互联网 发布:手机指纹锁软件 编辑:程序博客网 时间:2024/06/07 09:30
AVL的插入建立算法,用到了递归,且要分好几种一般情况来解决各类情况。
总体分为四种情况,
LL型,LR型,RR型,RL型;
下面说一下LL 型,和LR型的情况,另外两种的情况与这两种为镜像关系;
LL型,LR型,设结点A,A是离插入点最近,且平衡因子为1,(结点平衡因子左子树深度减去右子树深度)
LL型:
在A的左子树根节点的左子树上插入结点F,导致A结点的平衡因子又1变到了2, 所以对A结点要进行右旋操作
代码中的
R_rotate(a)
具体实现过程如图
------------A结点右旋-------------------->
F点为插入点,
注意:在代码中还有修改相关点的平衡因子
LR型:
在A的左子树根节点的右子树上插入结点F,导致A结点的平衡因子又1变到了2,所以对、要进行两次操作,先左旋,再右旋
代码中的:
L_rotata(A->lchild); R_rotate(A);
LR再细分有两种情况
插入点为左孩子还是右孩子
代码中的体现是
Bstree 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; }关系到相关结点平衡因子的修改。如有疑惑可以看下面的图
1.插入点为左孩子
--先对B结点进行左旋-,--->----对A右旋-----> 变成了LL的情况,在对A进行右旋即可
但是不要忘了修改相关结点的平衡因子。
2.插入点为右孩子
--先对B结点进行左旋-,--->--对A右旋----->
变成了LL的情况,在对A进行右旋即可
但是不要忘了修改相关结点的平衡因子。
下面是完整代码,没有写删除代码,和查询代码,
#include<iostream>#include<fstream>#include<cstdlib>#include<queue>using namespace std;//平衡二叉树的建立,遍历,,struct Bstnode{int data;int bf;//平衡因子Bstnode*lchild,*rchild;};typedef Bstnode * Bstree;#define LH +1#define EH 0#define RH -1void R_rotate(Bstree &p){//右旋,Bstree lc=p->lchild;p->lchild=lc->rchild;lc->rchild=p;p=lc;}void L_rotata(Bstree &p){//左旋,Bstree rc=p->rchild;p->rchild=rc->lchild;rc->lchild=p;p=rc;}void Leftbalance(Bstree &T){//左子树的平衡处理Bstree lc=T->lchild;switch(lc->bf){//LL的情况case LH: T->bf=lc->bf=EH; R_rotate(T);break;case RH://LR的情况,同时针对rd上的不同情况,进行对T,lc的平衡因子的设置 Bstree 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_rotata(T->lchild); R_rotate(T);}}void Rightbalance(Bstree &T)//右子树的平衡处理,与左子树的平衡处理类似{Bstree rc=T->rchild;switch (rc->bf){case RH: T->bf=rc->bf=EH; L_rotata(T);break;case LH: Bstree ld=rc->lchild; switch(ld->bf){case LH: T->bf=EH; rc->bf=RH;break;case EH: T->bf=rc->bf=EH;break;case RH: T->bf=LH; rc->bf=EH;break; } ld->bf=EH; R_rotate(T->rchild); L_rotata(T);}}bool InsertAVL(Bstree &T,int e,bool &taller){if(!T){//此结点为空,则插入,并设置该点平衡因子为0,taller为true,长高了 T=new Bstnode; T->data =e; T->lchild=T->rchild=NULL; T->bf=EH; taller=true;}else{ if(e==T->data){taller =false; return 0;}//已经存在,不插入,返回0;if(e<T->data){//如果e小于本结点,则继续在左子树搜索,if(!InsertAVL(T->lchild,e,taller))return 0;//未插入,返回0;if(taller)//已经插入到了左子树,则要检查平衡度,{ //注意!检查平衡度是由下往上的,哪个结点的失去平衡,则对该结点进行平衡操作switch(T->bf){case LH: //本结点本来左比右高,现在插入了,所以要做平衡处理 Leftbalance(T);taller=false; break;case EH: //本来等高,现在插入了,所以本结点平衡因子为1;taller 设为false ,进入下一个递归的时候,不需要在检查平衡; T->bf=LH; taller=true;break;case RH://本来右边高,现在插入了,所以本结点平衡因子为0;taller 设为false ,进入下一个递归的时候,不需要在检查平衡; T->bf =EH; taller=false; break; }}}else{//在右子树中查找 if(!InsertAVL(T->rchild,e,taller))return 0;//未插入,返回0; if(taller){ //同上,检查平衡 switch(T->bf){ case LH://本来左高,现在等高 T->bf=EH; taller=false; break; case EH://本来平衡,现在右增高了,所以本结点平衡因子为-1.taller为true,进入下一个递归是继续检查平衡, T->bf=RH;taller=true;break; case RH://本来右高,现在右又增高了,所以失去平衡,对该节点进行平衡处理 Rightbalance(T);taller=false;break; } }}}return 1;}void visit(int c){cout<<c<<" ";}void cengcitravel(Bstree T){ Bstree p; queue<Bstree>sq; sq.push(T);while(!sq.empty()){ p=sq.front(); visit(p->data);if(p->lchild)sq.push(p->lchild);if(p->rchild)sq.push(p->rchild); sq.pop();}}int main(){ int x;Bstree T=NULL;bool f=false;while(cin>>x){ InsertAVL(T,x,f);}cin.clear();cengcitravel(T);//输出序列cout<<endl;return 0;}
0 0
- C++代码,数据结构-平衡二叉树
- 数据结构 - 平衡二叉树
- 数据结构: 平衡二叉树
- 数据结构 平衡二叉树
- 【数据结构】平衡二叉树
- 数据结构&&平衡二叉树
- 数据结构--平衡二叉树
- 数据结构--平衡二叉树
- 数据结构---平衡二叉树
- 数据结构--平衡二叉树
- 数据结构 平衡二叉树
- 数据结构-平衡二叉树
- 平衡二叉树 代码
- 数据结构之平衡二叉树
- 数据结构 - 平衡二叉树 AVL
- 数据结构之 平衡二叉树
- 【数据结构】平衡二叉树_AVLTree
- 数据结构之平衡二叉树
- java1.5后的多线程框架
- JSP 使用<%@include%>报Duplicate local variable path 错误 解决方法
- Unity结合ZXing生成二维码并保存
- Android项目遇到"TheType R is already defined"
- php CGI与CLI与SAPI名词解释
- C++代码,数据结构-平衡二叉树
- Unity3D 场景编辑器扩展学习笔记-EditorWindow
- Qt for Android on Mac OSX部署
- 菜鸟入门:Java语言学习六大要点
- [MySQL binlog]彻底解析Mixed日志格式的binlog
- Json.Net用法
- UVA 11624 Fire!(两次BFS、超级源)
- java内部类的作用分析
- 10129 - Play on Words(欧拉道路<有向图>)