平衡二叉树(AVL树)的创建,查找
2016-02-01 15:30
597 查看
#include<stdio.h> #include<malloc.h> #define MAXSIZE 10 int a[MAXSIZE]={10,23,22,4,5,6,66,13,1,0}; typedef struct node { int key; //关键字项 int bf; //平衡因子 struct node *lchild,*rchild; //左右孩子指针 }BSTnode; void LeftProcess(BSTnode *&p,int &taller); void RightProcess(BSTnode *&p,int &taller); void Delete2(BSTnode *q,BSTnode *&r,int &taller); void LeftProcess1(BSTnode *&p,int &taller); void RightProcess1(BSTnode *&p,int &taller); int InsertAVL(BSTnode *&b,int k,int &taller) { if(b==NULL) //原树为空树,插入新节点,树长高,置taller=1 { b=(BSTnode *)malloc(sizeof(BSTnode)); b->key=k; b->lchild=b->rchild=NULL; b->bf=0; taller=1; } else { if(k==b->key) //树中已存在和k相同关键字的节点,不能插入 { taller=0; return 0; } if(k<b->key) //应继续在*b的左子树中搜索,即在左子树插入 { if((InsertAVL(b->lchild,k,taller))==0)//未插入 return 0; if(taller==1) //已插入*b的左子树,左子树长高 LeftProcess(b,taller); } else //应继续在*b的右子树中搜索,即在右子树插入 { if((InsertAVL(b->rchild,k,taller))==0)//未插入 return 0; if(taller==1) //已插入*b的右子树,右子树长高 RightProcess(b,taller); } } } void LeftProcess(BSTnode *&p,int &taller) { BSTnode *p1,*p2; if(p->bf==0) //情况1,插入前p->bf=0 { p->bf=1; taller=1; //子树增高 } else if(p->bf==-1) //情况2,插入前p->bf=-1 { p->bf=0; taller=0; //子树没有增高 } else //情况3,p->bf=1 { p1=p->lchild; if(p1->bf==1) //做LL调整 { p->lchild=p1->rchild; p1->rchild=p; p->bf=p1->bf=0; p=p1; } else if(p1->bf==-1) //做LR调整 { p2=p1->rchild; p1->rchild=p2->lchild; p2->lchild=p1; p->lchild=p->rchild; p2->rchild; if(p2->bf==0) //K处在*b位置上(叶子节点) p->bf=p1->bf=0; else if(p2->bf==1) //k处于*b的左子树上 { p1->bf=0; p->bf=-1; } else //k处在*b的右子树上 { p1->bf=1; p->bf=0; } p=p2; //仍然将p指向新的根节点,并置其bf值为0 p->bf=0; } taller=0; //子树没有增高 } } void RightProcess(BSTnode *&p,int &taller) { BSTnode *p1,*p2; if(p->bf==0) //情况1,插入前p->bf=0 { p->bf=-1; taller=-1; //子树增高 } else if(p->bf==1) //情况2,插入前p->bf=-1 { p->bf=0; taller=0; //子树没有增高 } else //情况3,p->bf=1 { p1=p->rchild; if(p1->bf==-1) //做RR调整 { p->rchild=p1->lchild; p1->lchild=p; p->bf=p1->bf=0; p=p1; } else if(p1->bf==1) //做RL调整 { p2=p1->lchild; p1->lchild=p2->rchild; p2->rchild=p1; p->rchild=p->lchild; p2->lchild; if(p2->bf==0) //K处在*b位置上(叶子节点) p->bf=p1->bf=0; else if(p2->bf==-1) //k处于*b的左子树上 { p1->bf=0; p->bf=1; } else //k处在*b的右子树上 { p1->bf=-1; p->bf=0; } p=p2; //仍然将p指向新的根节点,并置其bf值为0 p->bf=0; } taller=0; //子树没有增高 } } void InOrder(BSTnode *p) //中序遍历 { if(p!=NULL) { InOrder(p->lchild); printf("%d ",p->key); InOrder(p->rchild); } } int DeleteAVL(BSTnode *&p,int x,int &taller)//从根节点为*p的AVL树中删除关键字为x的节点 { int k; BSTnode *q; if(p==NULL) return 0; else if(x<p->key) { k=DeleteAVL(p->lchild,x,taller); if(taller==1) LeftProcess1(p,taller); //需要左处理 return k; } else if(x>p->key) { k=DeleteAVL(p->rchild,x,taller); if(taller==1) RightProcess1(p,taller); //需要右处理 return k; } else //找到了关键字为x的节点,由p指向它 { q=p; if(p->rchild==NULL) //被删除节点右子树为空 { p=p->lchild; free(q); taller=1; } else if(p->lchild==NULL) //被删除节点左字树为空 { p=p->rchild; free(q); taller; } else //被删除节点左右子树都不为空 { Delete2(q,q->lchild,taller); if(taller==1) LeftProcess1(q,taller); //需要左处理 p=q; } return 1; } } void Delete2(BSTnode *q,BSTnode *&r,int &taller)//被删除节点左右子树都不为空 { if(r->rchild==NULL) { q->key=r->key; q=r; r=r->lchild; free(q); taller=1; } else { Delete2(q,r->rchild,taller); //递归找最右下节点,找到后进行删除 if(taller==1) RightProcess1(r,taller); //需要右处理 } } void LeftProcess1(BSTnode *&p,int &taller) //删除左处理算法 { BSTnode *p1,*p2; if(p->bf==1) //情况1,p-bf=1; { p->bf=0; taller=1; } else if(p->bf==0) //情况2,p->bf=0; { p->bf=-1; taller=0; } else { p1=p->rchild; if(p1->bf==0) { p->rchild=p1->lchild; p1->lchild=p; p1->bf=1; p->bf=-1; p=p1; taller; } else if(p1->bf==-1) { p->rchild=p1->lchild; p1->lchild=p; p->bf=p1->bf=0; p=p1; taller=1; } else { p2=p1->lchild; p1->lchild=p2->rchild; p2->rchild=p1; p->rchild=p2->lchild; p2->lchild=p; if(p2->bf==0) { p->bf=0; p1->bf=0; } else if(p2->bf==-1) { p->bf=1; p1->bf=0; } else { p->bf=0; p1->bf=-1; } p2->bf=0; p=p2; taller=1; } } } void RightProcess1(BSTnode *&p,int &taller) //删除右处理算法 { BSTnode *p1,*p2; if(p->bf==-1) //情况1,p-bf=-1; { p->bf=0; taller=-1; } else if(p->bf==0) //情况2,p->bf=0; { p->bf=1; taller=0; } else { p1=p->lchild; if(p1->bf==0) { p->lchild=p1->rchild; p1->rchild=p; p1->bf=-1; p->bf=1; p=p1; taller; } else if(p1->bf==1) { p->lchild=p1->rchild; p1->rchild=p; p->bf=p1->bf=0; p=p1; taller=-1; } else { p2=p1->rchild; p1->rchild=p2->lchild; p2->lchild=p1; p->lchild=p2->rchild; p2->rchild=p; if(p2->bf==0) { p->bf=0; p1->bf=0; } else if(p2->bf==1) { p->bf=-1; p1->bf=0; } else { p->bf=0; p1->bf=1; } p2->bf=0; p=p2; taller=-1; } } } int main() { BSTnode *p; int i,taller; for(i=0;i<MAXSIZE;i++) //将数组a[]中元素插入到AVL InsertAVL(p,a[i],taller); printf("中序遍历:\n"); //中序遍历,将数组中的元素从小到大排列 InOrder(p); printf("\n"); DeleteAVL(p,4,taller); printf("删除关键字为4的结点后,中序遍历:\n"); InOrder(p); printf("\n"); }
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- JavaScript演示排序算法
- 我是运营,我没有假期
- AVL树-自平衡二叉查找树(Java实现)
- 如何写好 C main 函数
- Tomcat端口被占用解决方法(不用重启)
- DB2数据库的安装
- C#实现把指定数据写入串口
- “传奇”图象数据存储方式
- 修复mysql数据库
- Lua和C语言的交互详解
- 浅析SQL数据操作语句
- SQLServer 数据导入导出的几种方法小结
- MySQL数据备份之mysqldump的使用详解
- 超大数据量存储常用数据库分表分库算法总结
- C#实现窗体间传递数据实例
- SQL Server误区30日谈 第18天 有关FileStream的存储,垃圾回收以及其它
- 给你的数据库文件减肥
- Oracle数据更改后出错的解决方法
- linux----->shell高级编程----1