SPLAY树各种操作--链表

SPLAY树各种操作

1.旋转

2.插入

3.删除

4.查找

5前驱

6.后继

7第k小/大

8根据秩求元素

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 preordertravel( Node p )
{
if( p )
{
if( p->pf )
printf("%d它得父亲节点为%d\n", p->v, p->pf->v);
else
printf("%d它得父亲节点为空\n", p->v);
preordertravel(p->child[0]);
preordertravel(p->child[1]);
}
}

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
Node 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;
while( scanf("%d",&N) != EOF )
{
for( int i = 1; i <= N; i++)
{
scanf("%d",&t);
Node q = NewNode( t );
insert(root, q, NULL);
}
preordertravel( root );
while( 1 )
{
scanf("%d",&t);
del(t);
preordertravel( root );
scanf("%d",&t);
printf("第%d小的数是%d\n",t,OS_select(root,t)->v);
scanf("%d",&t);
printf("该元素是第%d小\n",OS_rank(t));
printf("请输入你要查找的后继前驱:\n");
scanf("%d",&t);
Node p = splay_find(root, t);
Node p1 = Get_Prev(p);
Node q1 = Get_Next(p);
if( p1 == NULL && q1 == NULL)
printf("后继为空 前驱为空\n");
else if(p1 == NULL && q1 != NULL)
printf("后继为%d 前驱为空\n",q1->v);
else if( q1 == NULL && p1 != NULL )
printf("后继为空 前驱为%d\n",p1->v);
else
printf("前驱为%d 后继为%d \n",p1->v, q1->v);
}
puts("");
preordertravel( root );
}
return 0;
}



posted on 2012-03-05 00:40  more think, more gains  阅读(344)  评论(0编辑  收藏  举报

导航