1005 container

对一种数据结构有两种操作:

1.是插入元素

2.输出中位数,并且删除之。

数据结构题,splay水过。

View Code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;

//节点定义
typedef struct node
{
  node *child[2], *pf;
  int v, size;
}*Node;
Node root = NULL;


void update( Node p )
{
  if( p == NULL)
    return;
  else if( p->child[0] && p->child[1] )
    p->size = p->child[0]->size + p->child[1]->size + 1;
  else if( p->child[0])
    p->size = p->child[0]->size + 1;
  else if( p->child[1])
    p->size = p->child[1]->size + 1;
  else
    p->size = 1;
}

//左孩子0,右孩子1
void Rotate(Node p, int x)
{
 
  Node q = p->child[x];
  p->child[x] = q->child[!x];
  if( q->child[!x] )
    q->child[!x]->pf = p;
  q->child[!x] = p;
  if( p->pf )
  {
  if( p->pf->child[x] == p)
      p->pf->child[x] = q;
  else 
      p->pf->child[!x] = q;
  }
  q->pf = p->pf;
  if( p->pf == NULL )
    root = q;
  p->pf = q;
  update(p);
  update(q);
}

void splay( Node p, Node q)
{
   while( p->pf != q )
   {  
      Node p1 = p->pf;
      if( p1->pf == q )
      {
         if(p1->child[0] == p)
         Rotate(p1, 0);
         else
         Rotate(p1, 1);
      }
     else if( p1->pf->child[0] == p1 )
      { 
        if( p1->child[0] == p )
        {
            Rotate(p1->pf, 0);
            Rotate(p1, 0);
        }
        else
        {   
           
            Rotate(p1,1);
            Rotate(p->pf,0);
        } 
      }
      else if( p1->pf->child[1] == p1 )
      {
         if( p1->child[1] == p )
         {
             Rotate(p1->pf, 1);
             Rotate(p1, 1);
         }
         else
         {  
           
             Rotate(p1, 0);
             Rotate(p->pf, 1);
         } 
      }
   }
}

void insert(Node &p, Node q, Node father)
{
   if( p == NULL )
   {
       p = q;
       p->pf = father;
       splay(p,NULL);
       return; 
   }
   if( p->v > q->v )
       insert(p->child[0], q, p);
   else
       insert(p->child[1], q, p);
   update(p);
}   


Node NewNode(int t)
{
    Node q = new node;
    q->child[0] = NULL;
    q->child[1] = NULL;
    q->pf = NULL;
    q->v = t;
    return q;
}

Node Get_Min(Node p)
{
   Node q1 = p, q2;
   while( q1 )
   {
     q2 = q1;
     q1 = q1->child[0];
   }
   return q2;
}

Node Get_Max(Node p)
{
  Node q1 = p, q2;
  while( q1 )
  {
     q2 = q1;
     q1 = q1->child[1];
  }
  return q2;
}

Node splay_find(Node p, int x )
{
  if( p->v == x )
    return p;
  if( p->v > x )
    return splay_find(p->child[0], x);
  else
    return splay_find(p->child[1], x);
}

//求前驱    
Node Get_Prev(Node p)
{
  Node q = p->pf;
  if( p->child[0] )
    return Get_Max(p->child[0]);
  while( q != NULL && p == q->child[0])
  {
    p = q;
    q = q->pf;
  }
  return q;
}  


//求后继
Node Get_Next(Node p)
{
 Node q = p->pf;
 if( p->child[1] )
    return Get_Min(p->child[1]);
 while( q != NULL && p == q->child[1] )
 {
   p = q;
   q = q->pf;
 }
 return q;
}


Node joint(Node p1, Node p2)
{
  if( p1 )
    p1->pf = NULL;
  if( p2 )
    p2->pf = NULL;
  if( !p1 )
    return p2;
  if( !p2 )
    return p1;
  p1 = Get_Max(p1);
  splay(p1,NULL);
  p1->child[1] = p2;
  p2->pf = p1;
  update(p2);
  update(p1);
  return p1;
}

void del(int x)
{
   Node p = splay_find(root, x);
   splay(p, NULL);
   root = joint(p->child[0], p->child[1]);
}

Node OS_select(Node p, int k)
{
   int num = 1;
   if( p->child[0] )
    num = p->child[0]->size + 1;
   if( num == k)
    return p;
   if( num < k )
     return OS_select(p->child[1], k - num);
   else
     return OS_select(p->child[0], k);
}

int OS_rank(int x)
{
  Node p = splay_find(root, x);
  Node q = p;
  int num = 1;
  if( p->child[0] )
    num = p->child[0]->size + 1;
  while( q != root )
  {
     q = q->pf;
     if( q )
     {
       if( p == q->child[1])
            num += q->child[0]->size + 1;
     }
     p = q;
  }
  return num;
}

int main( )
{
   int N, sum = 0, ans, a, b, num = 0, t, cnum = 0;
   while(  scanf("%d",&N) != EOF )
   {  
      cnum = 0;
      root = NULL;
      for( int i = 1; i <= N; i++)
      {  
         scanf("%d",&a);
         if( a ==  0 )
         {
          scanf("%d",&t);
          Node q = NewNode( t );
          insert(root, q, NULL);
          cnum++;
         }
         else
         { 
           if( cnum <= 0 )
               puts("No Element!");
           else
           {
            int pp = OS_select(root,(cnum + 1) / 2)->v;
            printf("%d\n",pp);
            del(pp);
            cnum--;
           }
             
         }
      }
      puts("");
   }
   return 0;
}

转载于:https://www.cnblogs.com/tangcong/archive/2012/08/16/2642971.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值