您的位置:首页 > 产品设计 > UI/UE

poj 3481 Double Queue

2012-09-20 23:38 302 查看
http://poj.org/problem?id=3481

  第一道SBT的题,十分简单,1y。

  这题用优先级来排序,查找优先级最小/最大的元素,返回其值并删除节点。

  构造popHead和popTail两个函数,搜索最小/最大的节点。因为构树的时候没有构造父节点指针,所以对节点修改的函数都必须用引用符号来继承上一结点的属性。

View Code

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

struct SBTNode{
SBTNode *left, *right;
int key, size, id;
SBTNode(int k, int i){
key = k;
id = i;
size = 1;
left = right = NULL;
}
};

struct SBT{
SBTNode *root;

SBT(){
root = NULL;
}

void rightRotate(SBTNode *&x){
SBTNode *y = x->left;

x->left = y->right;
y->right = x;
y->size = x->size;

int ls = x->left ? x->left->size : 0;
int rs = x->right ? x->right->size : 0;

x->size = ls + rs + 1;
x = y;
}

void leftRotate(SBTNode *&x){
SBTNode *y = x->right;

x->right = y->left;
y->left = x;
y->size = x->size;

int ls = x->left ? x->left->size : 0;
int rs = x->right ? x->right->size : 0;

x->size = ls + rs + 1;
x = y;
}

void maintain(SBTNode *&T, bool rightDeeper){
if (!T) return ;
if (!rightDeeper){
if (T->left == NULL) return ;

int rs = T->right ? T->right->size : 0;

if (T->left->left && T->left->left->size > rs){
rightRotate(T);
}
else if (T->left->right && T->left->right->size > rs){
leftRotate(T->left);
rightRotate(T);
}
else return ;
}
else {
if (T->right == NULL) return ;

int ls = T->left ? T->left->size : 0;

if (T->right->right && T->right->right->size > ls){
leftRotate(T);
}
else if (T->right->left && T->right->left->size > ls){
rightRotate(T->right);
leftRotate(T);
}
else return ;
}
maintain(T->left, false);
maintain(T->right, true);
maintain(T, false);
maintain(T, true);
}

void ins(SBTNode *&T, SBTNode *x){
if (!T){
T = x;
return ;
}
T->size++;
if (x->key < T->key){
ins(T->left, x);
}
else{
ins(T->right, x);
}
maintain(T, x->key >= T->key);
}

void del(SBTNode *&T, int key){
if (!T) return ;
T->size--;
if (key < T->key) del(T->left, key);
else if (key > T->key) del(T->right, key);
else{
SBTNode *t;

if (!T->left && !T->right){
delete T;
T = NULL;
}
else if (!T->right){
t = T;
T = T->left;
delete t;
}
else if (!T->left){
t = T;
T = T->right;
delete t;
}
else{
t = T->right;
while (t->left) t = t->left;
T->key = t->key;
T->id = t->id;
del(T->right, t->key);
}
}
}

/******the following two funtions is modeled after the delete funtion******/
int popHead(SBTNode *&T){
SBTNode *p = T;

if (!T) return 0;
T->size--;
if (T->left) return popHead(T->left);
else{
T = T->right;

int ret = p->id;

delete p;
return ret;
}
}

int popTail(SBTNode *&T){
SBTNode *p = T;

if (!T) return 0;
T->size--;
if (T->right) return popTail(T->right);
else{
T = T->left;

int ret = p->id;

delete p;
return ret;
}
}

void print(SBTNode *T){
if (!T) return ;
printf("cur %d : id %d key %d left %d right %d size %d\n", T, T->id, T->key, T->left, T->right, T->size);
print(T->left);
print(T->right);
}
}T;

void work(){
int op;

T.root = NULL;
while (~scanf("%d", &op)){
switch (op){
case 1:{
int id, wt;

scanf("%d%d", &id, &wt);

SBTNode *tmp = new SBTNode(wt, id);
T.ins(T.root, tmp);
//T.print(T.root);
}
break;
case 2:{
printf("%d\n", T.popTail(T.root));
//T.print(T.root);
}
break;
case 3:{
printf("%d\n", T.popHead(T.root));
//T.print(T.root);
}
break;
default: return ;
}
}
}

int main(){
//freopen("in", "w", stdout);
work();

return 0;
}


——written by Lyon
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: