参考博客:数据结构 AVL
代码:
指针实现
/*仿一个博客的AVL*/
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#include<ctime>
#include<cstring>
#include<string>
#define LL __int64
#define INF 0x3f3f3f3f3f
using namespace std;
struct node
{
int val;
int height;
node* l;
node* r;
};
node root;
int max(int a, int b)
{
return a>b;
}
int height(node *p)
{
if(p) return p->height;
return 0;
}
node* maximum(node* p)
{
if(p)
{
while(p->r) p=p->r;
return p;
}
return NULL;
}
node* minimum(node* p)
{
if(p)
{
while(p->l) p=p->l;
return p;
}
return NULL;
}
node* LeftRotation(node* p)
{
node *q = p->r;
p->r = q->l;
q->l = p;
p->height = max(height(p->l), height(p->r)) + 1;
q->height = max(height(q->l), height(q->r)) + 1;
return q;
}
node* RightRotation(node* p)
{
node *q = p->l;
p->l = q->r;
q->r = p;
p->height = max(height(p->l), height(p->r)) + 1;
q->height = max(height(q->l), height(q->r)) + 1;
return q;
}
node* RLeftRotation(node* p)
{
p->r = RightRotation(p->r);
return LeftRotation(p);
}
node* LRightRotation(node* p)
{
p->l = LeftRotation(p->l);
return RightRotation(p);
}
node* InsertNode(node* &p, int val)
{
if(!p)
{
p = new node;
p->height=0;
p->l=NULL;
p->r=NULL;
p->val=val;
}
else if(val > p->val)
{
p->r = InsertNode(p->r, val);
if(height(p->r) - height(p->l)==2) //插入失衡
{
if(val > p->r->val) p = LeftRotation(p);
else p = RLeftRotation(p);
}
}
else if(val < p->val)
{
p->l = InsertNode(p->l, val);
if(height(p->l) - height(p->r)==2) //插入失衡
{
if(val < p->l->val) p = RightRotation(p);
else p = LRightRotation(p);
}
}
p->height = max(height(p->l), height(p->r)) + 1;
return p;
}
node* del(node* &p, int val)
{
if(p)
{
if(val == p->val)
{
if(p->l && p->r)//左右都不为空
{
if(height(p->l) > height(p->r))
{
node* q = maximum(p->l);
p->val = q->val;
p->l = del(p->l, q->val);
}
else
{
node* q = minimum(p->r);
p->val = q->val;
p->r = del(p->r, q->val);
}
}
else
{
node* q = p;
if(p->l) p=p->l;
else if(p->r) p=p->r;
return NULL;
}
}
else if(val > p->val)
{
p->r = del(p->r, val);
if(height(p->l) - height(p->r) == 2)
{
if(height(p->l->r)>height(p->l->l))
{
p = LRightRotation(p);
}
else p = RightRotation(p);
}
}
else if(val < p->val)
{
p->l = del(p->l, val);
if(height(p->r) - height(p->l) ==2)
{
if(height(p->r->l)>height(p->r->r))
{
p=RLeftRotation(p);
}
else p = LeftRotation(p);
}
}
return p;
}
return NULL;
}
int query(int x)
{
node *p=root.l;
int k=0;
stack<node*>S;
if(!p) return false;
while(p || !S.empty())
{
while(p)
{
S.push(p);
p=p->l;
}
p=S.top();
S.pop();
k++;
if(k==x)
{
return p->val;
break;
}
p=p->r;
}
return false;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,x;
char c[4];
scanf("%d", &n);
root.l=root.r=NULL;
while(n--)
{
scanf("%s", c);
if(c[0]=='Y') printf("Single dog!\n");
else
{
scanf("%d", &x);
if(c[0]=='J') InsertNode(root.l, x);
else if(c[0]=='W') printf("%d\n", query(x));
else if(c[0]=='X') del(root.l, x);
}
}
return 0;
}
数组实现:
/***************
Problem from :数据结构
Problem describe :平衡树的应用
****************/
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#include<ctime>
#include<cstring>
#include<string>
#define LL __int64
#define INF 0x3f3f3f3f3f
using namespace std;
struct Tree{
int key, l, r, size;
}node[111111];
int root=0, top=0;
void left_rotation(int &x)
{
int y = node[x].r;
node[x].r = node[y].l;
node[y].l = x;
node[y].size = node[x].size;
node[x].size = node[node[x].l].size + node[node[x].r].size+1;
x = y;
}
void right_rotation(int &x)
{
int y = node[x].l;
node[x].l = node[y].r;
node[y].r = x;
node[y].size = node[x].size;
node[x].size = node[node[x].l].size + node[node[x].r].size+1;
x = y;
}
void maintain(int &root, bool flag)
{
if(flag == false)//false => 左
{
// root 的左儿子的左儿子的size>root的右儿子的size
if(node[node[node[root].l].l].size > node[node[root].r].size)
{
right_rotation(root);
}
// root 的左儿子的右儿子的size>root的右儿子的size
else if(node[node[node[root].l].r].size > node[node[root].r].size)
{
left_rotation(node[root].l);
right_rotation(root);
}
else return ;
}
else
{
// root 的右儿子的右儿子的size>root的左儿子的size
if(node[node[node[root].r].r].size > node[node[root].l].size)
{
left_rotation(root);
}
// root 的右儿子的左儿子的size>root的右儿子的size
else if(node[node[node[root].r].l].size > node[node[root].l].size)
{
right_rotation(node[root].r);
left_rotation(root);
}
else return ;
}
maintain(node[root].l,false);
maintain(node[root].r,true);
maintain(root,true);
maintain(root,false);
}
void insert(int &root, int key)
{
if(root==0)
{
root=++top;
node[root].l = node[root].r = 0;
node[root].size = 1;
node[root].key = key;
}
else
{
node[root].size ++;
if(key < node[root].key) insert(node[root].l, key);
else insert(node[root].r, key);
maintain(root, key>=node[root].key);
}
return ;
}
int remove(int &root, int key)
{
int d_key;
node[root].size--;
if( key == node[root].key || (key > node[root].key&& node[root].r==0)
|| (key < node[root].key&& node[root].l==0))
{
d_key = node[root].key;
if(node[root].l && node[root].r)
{
node[root].key = remove(node[root].l,node[root].key+1);
}
else
{
root = node[root].l + node[root].r;
}
}
else if(key > node[root].key)
{
d_key = remove(node[root].r, key);
}
else
{
d_key = remove(node[root].l, key);
}
return d_key;
}
int select(int &root,int k)//求第k小数
{
int r = node[node[root].l].size + 1;
if(r == k) return node[root].key;
else if(r < k) return select(node[root].r,k - r);
else return select(node[root].l,k);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,cnt=0,x;
char c[4];
scanf("%d", &n);
while(n--)
{
scanf("%s", c);
if(c[0]=='Y') printf("Single dog!\n");
else
{
scanf("%d", &x);
if(c[0]=='J') insert(root, x), cnt++;
else if(c[0]=='W') printf("%d\n", (x>cnt)?0:select(root, x));
else if(c[0]=='X') remove(root, x), cnt--;
}
}
return 0;
}