template<class DataType>
class SplayTree{
#define null 0
private:
int MAXSIZE;
int *l,*r,*p,*pool,*depth;
int top,root,tot;
DataType *key;
int malloc(DataType k){
int node;
if(top!=0){
node = pool[--top];
}else{
node = ++tot;
}
key[node] = k;
return node;
}
void free(int node){
l[node] = r[node] = p[node] = null;
pool[top++] = node;
}
void zig(int x){
int fa = p[x];
int ga = p[fa];
l[fa] = r[x];
p[l[fa]] = fa;
r[x] = fa;
p[fa] = x;
if(ga) l[ga]==fa?l[ga] = x:r[ga] = x;
p[x] = ga;
}
void zag(int x){
int fa = p[x];
int ga = p[fa];
r[fa] = l[x];
p[r[fa]] = fa;
l[x] = fa;
p[fa] = x;
if(ga) l[ga]==fa?l[ga] = x:r[ga] = x;
p[x] = ga;
}
/**
伸展到根rt处
**/
void splay(int x,int &rt){
while(p[x]){
int fa = p[x],ga = p[p[x]];
if(ga==null){
l[fa]==x?zig(x):zag(x);
}else{
if(l[ga]==fa){
if(l[fa]==x){
zig(fa);
zig(x);
}else{
zag(x);
zig(x);
}
}else{
if(r[fa]==x){
zag(fa);
zag(x);
}else{
zig(x);
zag(x);
}
}
}
}
rt = x;
}
int find_help(DataType goal,int rt){
if(rt==null) return null;
if(key[rt]==goal)return rt;
return goal<key[rt]?find_help(goal,l[rt]):find_help(goal,r[rt]);
}
//fa = p[rt]
int insert_help(DataType goal,int &rt,int fa){
if(rt==null){
rt = malloc(goal);
p[rt] = fa;//必须得修改新结点的父亲指针
return rt;
}
return goal<key[rt]?insert_help(goal,l[rt],rt):insert_help(goal,r[rt],rt);
}
int findmax_help(int rt){
int node = rt;//考虑空树的情况
while(node!=null&&r[node]!=null) node = r[node];
return node;
}
int findmin_help(int rt){
int node = rt;
while(node!=null&&l[node]!=null) node = l[node];
return node;
}
/**
将rt1 rt2 两颗BST合并成一棵BST
返回新BST的根
**/
int join(int &rt1,int &rt2){
if(rt1==null)return rt2;
if(rt2==null)return rt1;
int node = findmax_help(rt1);
splay(node,rt1); r[rt1] = rt2; p[rt2] = rt1;
return rt1;
}
/**
根据goal将一棵BST分裂成两颗BST
返回goal结点的位置
**/
int split(DataType goal,int &rt,int &rt1,int &rt2){
int node = find_help(goal,rt);
if(node!=null){
splay(node,rt);
rt1 = l[rt];
rt2 = r[rt];
p[rt1] = p[rt2] = null;
l[rt] = r[rt] = null;
}
return node;
}
//更新各结点深度
int refreshDepth(int rt,int dep){
if(rt==null)return 0;
depth[rt] = dep;
int t1 = refreshDepth(l[rt],dep+1);
int t2 = refreshDepth(r[rt],dep+1);
return max(max(t1,t2),dep);
}
public:
SplayTree(int maxsize){
MAXSIZE = maxsize;
depth = new int[MAXSIZE];
l = new int[MAXSIZE]; memset(l,0,sizeof(int)*MAXSIZE);
r = new int[MAXSIZE]; memset(r,0,sizeof(int)*MAXSIZE);
p = new int[MAXSIZE]; memset(p,0,sizeof(int)*MAXSIZE);
pool = new int[MAXSIZE]; memset(pool,0,sizeof(int)*MAXSIZE);
key = new DataType[MAXSIZE]; memset(key,0,sizeof(DataType)*MAXSIZE);
top = root = tot = 0;
}
~SplayTree(){
delete[] depth;
delete[] l;
delete[] r;
delete[] p;
delete[] pool;
delete[] key;
}
int find(DataType goal){
int node = find_help(goal,root);
if(node!=null){
splay(node,root);
return 1;
}
return 0;
}
int findmax(){
int node = findmax_help(root);
if(node!=null) splay(node,root);
return node;
}
int findmin(){
int node = findmin_help(root);
if(node!=null) splay(node,root);
return node;
}
void insert(DataType goal){
int node = insert_help(goal,root,p[root]);
splay(node,root);
}
int remove(DataType goal){
int rt1,rt2;
int node = split(goal,root,rt1,rt2);
if(node!=null){
free(root);
root = join(rt1,rt2);
}
return node;
}
DataType getValue(int node){
return key[node];
}
/*debug 查看树形*/
void bfs(){
int termi = refreshDepth(root,1);
cout<<termi<<endl;
queue<int> Q;
Q.push(root);
int flag = 1,dep = 1,cond = dep;
while(1){
int now = Q.front(); Q.pop();
if(cond==0){
dep++;
flag = flag*2;
cond = flag;
cout<<endl;
}
if(dep>termi)break;
cout<<"["<<key[now]<<"]"; cond--;
Q.push(l[now]);
Q.push(r[now]);
}
}
};
分享到:
相关推荐
splay tree C# code 伸展树的C#代码实现 我看到没有C#实现版本,所以就把java代码转化成C#实现了一把
伸展树(Splay tree)图解与实现(2020.10.22).pdf
erl-splay-tree:Erlang中的splay-tree实现
伸展数的主要难点:展开函数的实现。 基本操作插入、删除、查找都和展开函数相关。 插入:在根处按要插入的元素展开树,如果树中已经存在此节点,则此节点在展开后就是根;如果不存在节点,根处的元素是比欲插入节点...
游戏树展开树的简单实现。 所有函数都具有与 STL 映射函数类似的调用。细节此实现是出于教育目的。 对该库进行了基本测试。 如果您发现错误,请报告它,我会尝试修复它。特征C++11 组件前向迭代器和 const_iterator ...
POJ 3580代码 Splay tree实现
快速八叉树 :(非递归)和简单(<1000行代码)实现是直接从Wikipedia改编而成的,使用与相同的API来针对其他树运行基准测试。 该树基于D.Sleator自上而下的展开...S splaytree import SplayTree from 'splaytree'
红黑树、平衡二叉树、B树、二叉搜索树和SPlay树的C++源码实现,带工程
一个简单的 AVL树、splay树、以及二叉搜索树的代码实现 也可在我的github仓库中下载: https://github.com/yunwei37/myClassNotes
节点展开树展开树实现进行中...
给定一个长度为N的序列,每个序列的长度是一个整数。要支持以下三种操作: 将[L,R]这个区间所有数加上V. 将[L,R]这个区间翻转,例如 1234变成 4321 ...能力有限,实现可能有纰漏,也没有用到lazy_tag
该代码包括了二叉树、二叉查找树、平衡树的Java实现代码
此实现提供了类似哈希的界面,并且提供了Splay树中通常不存在的几个功能-有效删除通常访问最少的项,并提供额外的快速搜索选项。叶修剪由于八字树倾向于将自身与最常访问的元素一起组织到树的根部,因此最不频繁...
八叉树快速的八叉树实现为实习录入任务
SplayTree.h: Top-down splay tree TestSplayTree.cpp: Test program for splay trees RedBlackTree.h: Top-down red black tree TestRedBlackTree.cpp: Test program for red black trees Treap.h: Treap ...
java实现别踩白块儿源码唐ju ...展开树(SplayTree) 其他订单集合: 跳过清单(SkipList) 和别的... 基于AVL和Splay树的堆(AvlSplayHeap) 基于AVL树的堆并通过创建节点时间作为AVL树进行索引(同时...)
利用伸展树(Splay Tree)是一种二叉排序树,它能在O(log n)内完成插入、查找和删除操作。它由Daniel Sleator和Robert Tarjan创造。它的优势在于不需要记录用于平衡树的冗余信息。在伸展树上的一般操作都基于伸展...
Splay符号表该项目是Splay符号表的实现。 该项目的目的是利用备忘录来缓存结果和处理时间的速度。 计算二项式系数,并且可以比较记忆运行和非记忆运行的测试。 它是用Java编写的,是温哥华华盛顿州立大学高级数据...
待办事项清单一个用于组织您的待办事项列表的网络程序。... 我已经实现了一个LinkedList和一个Splay Tree来分别存储列表项和列表。 Cookies用于管理会话。 不过,它们会在首次启动网站24小时后重置。 居住在: :
哈希表及其实现 树木 binary trees n-ary trees trie-trees traversal balanced binary tree, red/black tree splay tree AVL tree Implementation 图表 There are 3 basic ways to represent a graph in memory...