【Naive|【Naive Splay Template】
写小作业的时候重新复习了一下splay
只支持插入,删除,查k大,查节点数。没有迭代器。
T类型需要重载==和<,要调用拷贝构造函数。
template
class Splay {
private:
struct node {
T v;
node *ch[2], *fa;
int size;
node(const T &a) : size(1), v(a), ch{nullptr, nullptr}, fa(nullptr) {};
void setc(node *r, int c) {
ch[c] = r;
if (r != nullptr) r->fa = this;
}
int pl() {
if (fa != nullptr) return fa->ch[1] == this;
else return 0;
}
void count() {
size = 1;
if (ch[0] != nullptr) size += ch[0]->size;
if (ch[1] != nullptr) size += ch[1]->size;
}
};
node *root;
void release(node *r) {
if (r == nullptr) return;
release(r->ch[0]);
release(r->ch[1]);
delete r;
}public:
Splay() : root(nullptr) {}~Splay() {
release(root);
}private:
void rotate(node *r) {
node *f = r->fa;
int c = r->pl();
if (f == root) r->fa = nullptr, root = r;
else f->fa->setc(r, f->pl());
f->setc(r->ch[c ^ 1], c);
r->setc(f, c ^ 1);
f->count();
}void splay(node *r, node *tar = nullptr) {
for(;
r->fa != tar;
rotate(r))
if (r->fa->fa != tar) rotate(r->fa->pl() == r->pl() ? r->fa : r);
r->count();
}void rm(node *);
public:
int size();
void remove(const T &);
void insert(const T &);
T *kth(int);
};
template
int Splay::size() {
if (root == nullptr) return 0;
else return root->size;
}template
void Splay::rm(node *r) {
node *f = nullptr;
if (r->ch[0] == nullptr && r->ch[1] == nullptr) {
if (r == root) root = nullptr;
else {
f = r->fa;
r->fa->setc(nullptr, r->pl());
delete r;
}
} else if (r->ch[0] == nullptr || r->ch[1] == nullptr) {
int c = r->ch[0] == nullptr;
node *t = r->ch[c];
while (t->ch[c ^ 1] != nullptr) t = t->ch[c ^ 1];
splay(t, r->fa);
r->fa->setc(nullptr, c ^ 1);
f = r->fa;
delete r;
} else {
node *h = r->ch[0], *t = r->ch[1];
while (h->ch[1] != nullptr)
h = h->ch[1];
while (t->ch[0] != nullptr) t = t->ch[0];
splay(h, r->fa);
splay(t, h);
t->setc(nullptr, 0);
delete r;
f = t;
}while (f != nullptr) {
f->count();
f = f->fa;
}
}template
void Splay::remove(const T &a) {
node *r = root;
while (r != nullptr) {
if (r->v == a) {rm(r);
break;
}
if (a < r->v) r = r->ch[0];
else r = r->ch[1];
}
}template
void Splay::insert(const T &a) {
node *r = root;
node *n = new node(a);
if (root == nullptr) {
root = n;
return;
}
while (r != nullptr) {
if (r->v == a) {delete n;
break;
}
if (a < r->v) {
if (r->ch[0] == nullptr) {
r->setc(n, 0);
splay(n);
break;
}
else
r = r->ch[0];
} else {
if (r->ch[1] == nullptr) {
r->setc(n, 1);
splay(n);
break;
}
else
r = r->ch[1];
}
}
}template
T *Splay::kth(int k) {
node *r = root;
while (r != nullptr) {
int l_size = 0;
if (r->ch[0] != nullptr) l_size = r->ch[0]->size;
if (l_size >= k) r = r->ch[0];
else if (l_size + 1 == k) return &r->v;
else {
k -= (l_size + 1);
r = r->ch[1];
}
}
return nullptr;
}
【【Naive|【Naive Splay Template】】转载于:https://www.cnblogs.com/abclzr/p/10589014.html
推荐阅读
- 宽容谁
- 我要做大厨
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘
- 学无止境,人生还很长