写小作业的时候重新复习了一下splay

只支持插入,删除,查k大,查节点数。没有迭代器。

T类型需要重载==和<,要调用拷贝构造函数。

template<class T>
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<class T>
int Splay<T>::size() {
if (root == nullptr) return 0;
else return root->size;
} template<class T>
void Splay<T>::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<class T>
void Splay<T>::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<class T>
void Splay<T>::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<class T>
T *Splay<T>::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;
}

最新文章

  1. 手把手教你搭建Hive Web环境
  2. text-indent:-9999px 字体隐藏问题
  3. 【iCore3 双核心板_FPGA】例程九:状态机实验——状态机使用
  4. go特性学习
  5. selenium如何操作cookies实现免登录
  6. zoj3819Average Score
  7. 解决:CWnd::SetWindowText报Assertion failure
  8. 创建Android Virtual Device
  9. 系列文章--精通CSS.DIV网页样式与布局学习
  10. DOM笔记(三):Element接口和HTMLElement接口
  11. Android 使用HTTP(get和post)方式登陆服务器
  12. leetcode Sum Root to Leaf Numbers(所有路径之和)
  13. qemu -hda /dev/sdc -m 1024 -vga std
  14. red hat 6.5 红帽企业Linux.6.5 yum This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register. 解决办法
  15. [USACO 09FEB]Fair Shuttle
  16. vue之$forceUpdate
  17. Eclipse中将web项目自动发布到Tomcat webapps下(转)
  18. Day7 错误和异常
  19. 如何安装和配置RabbitMQ(转载)
  20. Android Socket 知识点汇总

热门文章

  1. dockerfile创建镜像及容器
  2. windows环境cmd下执行jar
  3. Intent 对象在 Android 开发中的应用
  4. spin_lock &amp; mutex_lock的区别? 【转】
  5. codevs 1230 元素查找
  6. [转]关于MyEclipse下的项目无法使用BASE64Encoder问题的解决办法
  7. MAVLink v1.0详解——结构
  8. java基础37 集合框架工具类Collections和数组操作工具类Arrays
  9. Service(二):通信
  10. CentOS/Linux 网卡设置 IP地址配置