题目要求:插入数据,删除数据,查询数的排名,查询排名为x的 数,找前驱,找后继
- 旋转操作,左旋和右旋,旋转,旋转操作一定要符合先序遍历前后一致
点击查看代码
void rotate(int x){
int y = tr[x].p, z = tr[y].p;
int k = tr[y].s[1] == x;
tr[z].s[tr[z].s[1] == y] = x;
tr[tr[x].s[k ^ 1]].p = y;
tr[y].s[k] = tr[x].s[k ^ 1];
tr[x].s[k ^ 1] = y;
tr[x].p = z, tr[y].p = x;
pushup(y), pushup(x);
}
- 将x结点旋转到k结点下方,而且先序遍历前后一致
点击查看代码
void splay(int x, int k){
while(tr[x].p != k){
int y = tr[x].p, z = tr[y].p;
if(z != k)
(tr[y].s[0] == x) ^ (tr[z].s[0] == y)
? rotate(x) : rotate(y);
rotate(x);
}
if(k == 0) root = x;
}
3. 完整代码
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7;
struct node{
int s[2], p, v, cnt, size;
void init(int p1, int v1){
p = p1, v = v1;
cnt = size = 1;
}
}tr[N];
int root, idx;
void pushup(int x){
tr[x].size = tr[tr[x].s[0]].size +
tr[tr[x].s[1]].size + tr[x].cnt;
}
void rotate(int x){
int y = tr[x].p, z = tr[y].p;
int k = tr[y].s[1] == x;
tr[z].s[tr[z].s[1] == y] = x;
tr[tr[x].s[k ^ 1]].p = y;
tr[y].s[k] = tr[x].s[k ^ 1];
tr[x].s[k ^ 1] = y;
tr[x].p = z, tr[y].p = x;
pushup(y), pushup(x);
}
void splay(int x, int k){
while(tr[x].p != k){
int y = tr[x].p, z = tr[y].p;
if(z != k)
(tr[y].s[0] == x) ^ (tr[z].s[0] == y)
? rotate(x) : rotate(y);
rotate(x);
}
if(k == 0) root = x;
}
void find(int v){
int x = root;
while(tr[x].s[v > tr[x].v] && v != tr[x].v)
x = tr[x].s[v > tr[x].v];
splay(x, 0);
}
int get_pre(int v){
find(v);
int x = root;
if(tr[x].v < v) return x;
x = tr[x].s[0];
while(tr[x].s[1]) x = tr[x].s[1];
return x;
}
int get_suc(int v){
find(v);
int x = root;
if(tr[x].v > v) return x;
x = tr[x].s[1];
while(tr[x].s[0]) x = tr[x].s[0];
return x;
}
void del(int v){
int pre = get_pre(v);
int suc = get_suc(v);
splay(pre, 0), splay(suc, pre);
int del = tr[suc].s[0];
if(tr[del].cnt > 1)
tr[del].cnt --, splay(del, 0);
else
tr[suc].s[0] = 0, splay(suc, 0);
}
int get_rank(int v){
find(v);
return tr[tr[root].s[0]].size;
}
int get_val(int k){
int x = root;
while(1){
int y = tr[x].s[0];
if(tr[y].size + tr[x].cnt < k){
k -= tr[y].size + tr[x].cnt;
x = tr[x].s[1];
}
else{
if(tr[y].size >= k) x = tr[x]. s[0];
else break;
}
}
splay(x, 0);
return tr[x].v;
}
void insert(int v){
int x = root, p = 0;
while(x && tr[x].v != v)
p = x, x = tr[x].s[v>tr[x].v];
if(x) tr[x].cnt ++;
else{
x = ++ idx;
tr[p].s[v > tr[p].v] = x;
tr[x].init(p, v);
}
splay(x, 0);
}
int main(){
int n, op, x;
scanf("%d", &n);
insert(-1e9), insert(1e9);
while(n --){
scanf("%d%d", &op, &x);
if(op == 1) insert(x);
else if(op == 2) del(x);
else if(op == 3) printf("%d\n", get_rank(x));
else if(op == 4) printf("%d\n", get_val(x + 1));
else if(op == 5) printf("%d\n", tr[get_pre(x)].v);
else printf("%d\n", tr[get_suc(x)].v);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!