/******************************************************************
题目: 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树入门)的更多相关文章

  1. POJ 3481 Double Queue STLmap和set新学到的一点用法

    2013-08-08 POJ 3481  Double Queue 这个题应该是STL里较简单的吧,用平衡二叉树也可以做,但是自己掌握不够- -,开始想用两个优先队列,一个从大到小,一个从小到大,可是 ...

  2. POJ 3481 Double Queue(Treap模板题)

    Double Queue Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15786   Accepted: 6998 Des ...

  3. POJ-3481 Double Queue,Treap树和set花式水过!

                                                    Double Queue 本打算学二叉树,单纯的二叉树感觉也就那几种遍历了, 无意中看到了这个题,然后就 ...

  4. POJ 3481 Double Queue(STL)

    题意  模拟银行的排队系统  有三种操作  1-加入优先级为p 编号为k的人到队列  2-服务当前优先级最大的   3-服务当前优先级最小的  0-退出系统 能够用stl中的map   由于map本身 ...

  5. POJ 3481 Double Queue(set实现)

    Double Queue The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Buchares ...

  6. poj 2104 K-th Number (划分树入门 或者 主席树入门)

    题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法1:划分树 #include<cstdio> #include<cstring> #include<alg ...

  7. POJ 3481 Double Queue

    平衡树.. 熟悉些fhq-Treap,为啥我在poj读入优化不能用啊 #include <iostream> #include <cstdio> #include <ct ...

  8. POJ 3481 Double Queue (treap模板)

    Description The new founded Balkan Investment Group Bank (BIG-Bank) opened a new office in Bucharest ...

  9. PAT树_层序遍历叶节点、中序建树后序输出、AVL树的根、二叉树路径存在性判定、奇妙的完全二叉搜索树、最小堆路径、文件路由

    03-树1. List Leaves (25) Given a tree, you are supposed to list all the leaves in the order of top do ...

随机推荐

  1. SQL总结(六)触发器

    SQL总结(六)触发器 概念 触发器是一种特殊类型的存储过程,不由用户直接调用.创建触发器时会对其进行定义,以便在对特定表或列作特定类型的数据修改时执行. 触发器可以查询其他表,而且可以包含复杂的 S ...

  2. bzoj2515 Room

    Description Input Output 折半搜索,用散列表记录从原点出发,用了S(状压表示)这几种边(令|S|*2-1<=n),到达(x,y)的最大面积. #include<cs ...

  3. 小调网 经典电影 豆瓣评分 tampermonkey脚本

    // ==UserScript== // @name 小调网 // @namespace http://tampermonkey.net/ // @version 0.1 // @descriptio ...

  4. 图像滤波:Gabor滤波

  5. Swing列表框组件

    public class JListTest extends JFrame{    private static final long serialVersionUID=1L;        publ ...

  6. bootloader制作过程

    主机环境:Ubuntu10.04.4 LTS 使用工具:buildroot-201208 目  标  板:S3C2410 --------------------------------------- ...

  7. 用通俗易懂的大白话讲解Map/Reduce原理

    Hadoop简介 Hadoop就是一个实现了Google云计算系统的开源系统,包括并行计算模型Map/Reduce,分布式文件系统HDFS,以及分布式数据库Hbase,同时Hadoop的相关项目也很丰 ...

  8. oracle中的查询语句(关于出库入库信息表,明细表,把捆包箱表,单位信息表的集中查询)

    --查出所有现金中心的单位IDwith AllUnitas(select t.ORGANIZATIONID orgid,t.parentidfrom CDMS_ORGANIZATION t where ...

  9. dedecms代码研究七

    简单回顾一下,前面我们首页动态文件index.PHP调用arc.partview.class.php来初始化首页模板 arc.partview.class.php通过SetTemplet调用DedeT ...

  10. 0525 SCRUM项目7.0

    主题:在下一个SPRINT中做的更好 一,实验回顾总结 当谈到在一个团队里的收获,首当其冲的便是对于团队工作流程的切身体会.亲力亲为.从申报材料.问卷设计.访谈提纲.团队建设.书签制作到实地访谈.问卷 ...