poj 3841 Double Queue (AVL树入门)
/******************************************************************
题目: Double Queue(poj 3481)
链接: http://poj.org/problem?id=3481
算法: avl树(入门)
*******************************************************************/
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std; typedef struct Node ///树的节点
{
int val,data;
int h; ///以当前结点为根结点的数的高度
int bf; ///平衡因子(左子树高度与右子树高度之差)
Node *left,*right;
}Node; class AvlTree ///alv树,树中太多函数,用类来实现容易一些
{
private:
Node *root; ///树的根节点
public:
void Init() ///初始化树
{
root=NULL;
}
int Height(Node *T) ///取一个节点的高度
{
if (T==NULL) return ;
return T->h;
}
int Bf(Node *T) ///计算一个节点的平衡因子
{
if (T->left==T->right) return ;
if (T->left==NULL) return -(T->right->h); ///这里一定取负数(左子树高度与右子树高度之差)
if (T->right==NULL) return T->left->h;
return (T->left->h)-(T->right->h);
}
///四种旋转,不知为什么,自己多画一下就知道了。
Node *LL_rotate(Node *T) ///单向右旋平衡处理LL:由于在*T的左子树根结点的左子树上插入结点
{
Node *B=T->left;
T->left=B->right;
B->right=T;
T->h=max(Height(T->left),Height(T->right))+;
B->h=max(Height(B->left),Height(T->right))+;
T->bf=Bf(T);
B->bf=Bf(B);
return B;
}
Node *RR_rotate(Node *T) ///单向左旋平衡处理RR:由于在*T的右子树根结点的右子树上插入结点
{
Node *B=T->right;
T->right=B->left;
B->left=T;
T->h=max(Height(T->left),Height(T->right))+;
B->h=max(Height(B->left),Height(T->right))+;
T->bf=Bf(T);
B->bf=Bf(B);
return B;
}
Node *LR_rotate(Node *T) ///双向旋转平衡处理LR:由于在*T的左子树根结点的右子树上插入结点
{
T->left=RR_rotate(T->left);
T=LL_rotate(T);
return T;
}
Node *RL_rotate(Node *T) ///双向旋转平衡处理RL:由于在*T的右子树根结点的左子树上插入结点
{
T->right=LL_rotate(T->right);
T=RR_rotate(T);
return T;
}
void Insert(int v,int e) ///root是private,所以不能从主函数传入
{
Insert(root,v,e);
}
void Insert(Node *&T,int v,int e) ///插入新节点
{
if (T==NULL)
{
T=(Node *)malloc(sizeof(Node));
T->h=;
T->bf=;
T->val=v;
T->data=e;
T->left=T->right=NULL;
return ;
}
if (e<T->data) Insert(T->left,v,e);
else Insert(T->right,v,e);
T->h=max(Height(T->left),Height(T->right))+; ///计算节点高度
T->bf=Bf(T); ///计算平衡因子
if (T->bf>||T->bf<-) ///调整平衡,四种调整反法
{
if (T->bf>&&T->left->bf>) T=LL_rotate(T); ///如果T->bf > 1 则肯定有左儿子
if (T->bf<-&&T->right->bf<) T=RR_rotate(T); ///如果T->bf < -1 则肯定有右儿子
if (T->bf>1&&T->left->bf<0) T=LR_rotate(T);
if (T->bf<-1&&T->right>0) T=RL_rotate(T);
}
}
void Find(int flag) ///flag=1为找最大值,否则找最小值
{
if (root==NULL)
{
printf("0\n");
return ;
}
Node *temp=root;
if (flag) ///最大值一定最右边
{
while (temp->right)
temp=temp->right;
}
else
{
while (temp->left)
temp=temp->left;
}
printf("%d\n",temp->val);
Delete(root,temp->data); ///删除相应节点
}
void Delete(Node *&T,int e)
{
if (T==NULL) return ;
if (e<T->data) Delete(T->left,e);
else if (e>T->data) Delete(T->right,e);
else ///找到删除的节点
{
if (T->left&&T->right) ///删除的节点左右都还有节点
{
Node *temp=T->left; ///把左子树的最大值当做当前节点
while (temp->right) temp=temp->right; ///找最大值
T->val=temp->val;
T->data=temp->data;
Delete(T->left,temp->data); ///左子树最大值已近改为当前根节点,应该删除原来位置
}
else
{
Node *temp=T;
if (T->left) T=T->left; ///删除节点只存在左子树
else if (T->right) T=T->right; ///删除节点只有右子树
else ///删除节点没有孩子
{
free(T);
T=NULL;
}
if (T) free(temp);
return ;
}
}
T->h=max(Height(T->left),Height(T->right))+;
T->bf=Bf(T);
if (T->bf>||T->bf<-) ///删除后一定要调整
{
if (T->bf>&&T->left->bf>) T=LL_rotate(T);
if (T->bf<-&&T->right->bf<) T=RR_rotate(T);
if (T->bf>&&T->left->bf<) T=LR_rotate(T);
if (T->bf<-&&T->right>) T=RL_rotate(T);
}
}
void Free() ///由于内存是malloc出来的,最后一定要释放
{
FreeNode(root);
}
void FreeNode(Node *T)
{
if (T==NULL) return ;
if (T->right) FreeNode(T->right);
if (T->left) FreeNode(T->left);
free(T);
}
};
AvlTree T; int main()
{
T.Init();
int op;
while (~scanf("%d",&op)&&op)
{
if (op==)
{
int v,e;
scanf("%d%d",&v,&e);
T.Insert(v,e);
}
if (op==)
{
T.Find();
}
if (op==)
{
T.Find();
}
}
T.Free();
return ;
}
poj 3841 Double Queue (AVL树入门)的更多相关文章
- POJ 3481 Double Queue STLmap和set新学到的一点用法
2013-08-08 POJ 3481 Double Queue 这个题应该是STL里较简单的吧,用平衡二叉树也可以做,但是自己掌握不够- -,开始想用两个优先队列,一个从大到小,一个从小到大,可是 ...
- POJ 3481 Double Queue(Treap模板题)
Double Queue Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15786 Accepted: 6998 Des ...
- POJ-3481 Double Queue,Treap树和set花式水过!
Double Queue 本打算学二叉树,单纯的二叉树感觉也就那几种遍历了, 无意中看到了这个题,然后就 ...
- POJ 3481 Double Queue(STL)
题意 模拟银行的排队系统 有三种操作 1-加入优先级为p 编号为k的人到队列 2-服务当前优先级最大的 3-服务当前优先级最小的 0-退出系统 能够用stl中的map 由于map本身 ...
- POJ 3481 Double Queue(set实现)
Double Queue The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Buchares ...
- poj 2104 K-th Number (划分树入门 或者 主席树入门)
题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法1:划分树 #include<cstdio> #include<cstring> #include<alg ...
- POJ 3481 Double Queue
平衡树.. 熟悉些fhq-Treap,为啥我在poj读入优化不能用啊 #include <iostream> #include <cstdio> #include <ct ...
- POJ 3481 Double Queue (treap模板)
Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest ...
- PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由
03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...
随机推荐
- Unity Shader——Writing Surface Shaders(3)——Surface Shader Lighting Examples
Surface Shader 光照例子 这里有一些自定义光照模型和Surface Shaders的例子.通常的Surface Shader例子在这里. 由于延迟光照在某些自定义的逐材质光照模型中表现得 ...
- centos中开机时如何自启动samba服务器
解决办法如下:1.编辑rc.local文件#vi /etc/rc.d/rc.local2.加入如下启动命令/usr/sbin/apachectl start/etc/rc.d/init.d/mysql ...
- Action、Action<T>、Func<T> 匿名函数的写法
void ht_HLB_Set(Dictionary<int, int> dic) { //匿名函数 Action<int> fun = (int jhShare_Iid) = ...
- oracle控制文件丢失恢复
在学习群里有个同学误删除了控制文件,于是我也把自己数据库的控制文件删除了,看看能不能进行恢复,以下是整个实验的过程~~在做之前,先看看控制文件的备份方式:1.生成可以重建控制文件的脚本.2.备份二进制 ...
- 用Visual Studio调试Windows和驱动程序
由于本人能力有限,翻译不足之处敬请谅解,欢迎批评指正:sunylat@163.com Visual Studio版本:Visual Studio 2015企业版,中文环境. MSDN原文:https: ...
- 关于n!mod p
2016.1.26 让我们来研究一下关于n!在mod p下的性质,当然这里p是质数. 首先n!=a*pe,其中p不可整除a.我们现在来做两件事情,求e和a mod p. 显然,n/p表示[1,n]中p ...
- OS X 禁止Android File Transfer自动启动
操作步骤 关闭Android File Manager 在Activity Manager中退出Android File Manager Agent进程 在Applications中,将Android ...
- vs 2013 Express 无法启动程序xxx.exe,系统找不到指定文件
由于实验室有人用了含病毒的软件,网管把实验室出口给封了,周末人家又不上班.看样子树莓派是玩不成了,所以昨天在宿舍写windows程序,最基本的窗口程序,听说这段代码初学者至少要自己敲5遍以上.代码如下 ...
- 剑指Offer:面试题19——二叉树的镜像(java实现)
问题描述: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树结点定义为: public class TreeNode { int val = 0; TreeNode left = null; Tr ...
- 如何利用tomcat和cas实现单点登录(1):配置tomcat的ssl和部署cas
如何利用tomcat和cas实现单点登录,借鉴了网上的很多教程,主要分为以下几个步骤: 一:下载好cas,tomcat之后,首先配置tomcat: 用鼠标右键点击"计算机"→选择& ...