SDTU(3374) 数据结构实验之查找二:平衡二叉树
来源:互联网 发布:mac比较好用的浏览器 编辑:程序博客网 时间:2024/05/24 03:03
数据结构实验之查找二:平衡二叉树
Time Limit: 400ms Memory limit: 65536K
题目描述
根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。
输入
输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。
输出
输出平衡二叉树的树根。
示例输入
588 70 61 96 120
示例输出
70
提示
旋转:
对于一个平衡的节点,由于任意节点最多有两个儿子,因此高度不平衡时,此节点的两颗子树的高度差2.容易看出,这种不平衡出现在下面四种情况:
1、6节点的左子树3节点高度比右子树7节点大2,左子树3节点的左子树1节点高度大于右子树4节点,这种情况成为左左。
2、6节点的左子树2节点高度比右子树7节点大2,左子树2节点的左子树1节点高度小于右子树4节点,这种情况成为左右。
3、2节点的左子树1节点高度比右子树5节点小2,右子树5节点的左子树3节点高度大于右子树6节点,这种情况成为右左。
4、2节点的左子树1节点高度比右子树4节点小2,右子树4节点的左子树3节点高度小于右子树6节点,这种情况成为右右。
从图2中可以可以看出,1和4两种情况是对称的,这两种情况的旋转算法是一致的,只需要经过一次旋转就可以达到目标,我们称之为单旋转。2和3两种情况也是对称的,这两种情况的旋转算法也是一致的,需要进行两次旋转,我们称之为双旋转。
单旋转:
单旋转是针对于左左和右右这两种情况的解决方案,这两种情况是对称的,只要解决了左左这种情况,右右就很好办了。图3是左左情况的解决方案,节点k2不满足平衡特性,因为它的左子树k1比右子树Z深2层,而且k1子树中,更深的一层的是k1的左子树X子树,所以属于左左情况。
为使树恢复平衡,我们把k2变成这棵树的根节点,因为k2大于k1,把k2置于k1的右子树上,而原本在k1右子树的Y大于k1,小于k2,就把Y置于k2的左子树上,这样既满足了二叉查找树的性质,又满足了平衡二叉树的性质。
这样的操作只需要一部分指针改变,结果我们得到另外一颗二叉查找树,它是一棵AVL树,因为X向上一移动了一层,Y还停留在原来的层面上,Z向下移动了一层。整棵树的新高度和之前没有在左子树上插入的高度相同,插入操作使得X高度长高了。因此,由于这颗子树高度没有变化,所以通往根节点的路径就不需要继续旋转了。
双旋转:
对于左右和右左这两种情况,单旋转不能使它达到一个平衡状态,要经过两次旋转。双旋转是针对于这两种情况的解决方案,同样的,这样两种情况也是对称的,只要解决了左右这种情况,右左就很好办了。图4是左右情况的解决方案,节点k3不满足平衡特性,因为它的左子树k1比右子树Z深2层,而且k1子树中,更深的一层的是k1的右子树k2子树,所以属于左右情况。
为使树恢复平衡,我们需要进行两步,第一步,把k1作为根,进行一次右右旋转,旋转之后就变成了左左情况,所以第二步再进行一次左左旋转,最后得到了一棵以k2为根的平衡二叉树树。
#include<iostream>using namespace std;struct node{ int d; node *l,*r; int deep;};node *root;int deept(node *p) //计算树的深度{ if(!p) return -1; return p->deep;}void LL(node *&p){ //node *tmp=p; //中间变量,因为p是root的引用,交换p和q后,此时root不再是根节点 node *q=p->l; p->l=q->r; q->r=p; p->deep=max(deept(p->r),deept(p->l))+1; q->deep=max(p->deep,deept(q->l))+1; p=q; //将p和q交换 //q=tmp;}void RR(node *&p){ // node *tmp=p; node *q=p->r; p->r=q->l; q->l=p; p->deep=max(deept(p->l),deept(p->r))+1; q->deep=max(deept(q->r),p->deep)+1; p=q; // q=tmp;}void LR(node *&p){ RR(p->l); LL(p);}void RL(node *&p){ LL(p->r); RR(p);}void InsertT(node *&p,int k){ if(!p) //如果节点为空,就在此节点处加入k信息 { p=new node; p->d=k; p->l=p->r=NULL; p->deep=1; } else if(k<p->d) //如果k小于节点的值,就继续在节点的左子树中插入k { InsertT(p->l,k); if(deept(p->l)-deept(p->r)>1) //如果高度之差为2的话就失去了平衡,需要旋转 { if(k<p->l->d) LL(p); else LR(p); } } else if(k>p->d) { InsertT(p->r,k); if(deept(p->r)-deept(p->l)>1) { if(k>p->r->d) RR(p); else RL(p); } } p->deep=max(deept(p->l),deept(p->r))+1;}int main(){ int n; cin>>n; root=NULL; while(n--) { int x; cin>>x; InsertT(root,x); } cout<<root->d<<endl; return 0;}
- SDTU(3374) 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树【OJ--3374】
- SDUT 3374 数据结构实验之查找二:平衡二叉树
- 3374 数据结构实验之查找二:平衡二叉树
- 3374-数据结构实验之查找二:平衡二叉树
- 3374 数据结构实验之查找二:平衡二叉树
- SDUT 3374 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- SDUT 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- SDUT3374数据结构实验之查找二:平衡二叉树
- 数据结构实验之查找二:平衡二叉树
- OVMF基础
- 数据结构实验之二叉树一:树的同构
- not acceptable according to the request "accept" headers 问题解决
- hadoop fs 命令
- Mac中显示隐藏文件
- SDTU(3374) 数据结构实验之查找二:平衡二叉树
- HDU 1856More is better
- codeforces 702A 水 最长连续上什子序列
- 欢迎界面2秒跳转
- 机器学习实战——交叉验证
- [leetcode]143. Reorder List -- JavaScript 代码
- c#访问C盘user当前用户下的文件夹
- HDU:1541 Stars(树状数组)
- Vika and Squares