我土了....终于开始看平衡树了,以前因为害怕一直不敢看数据结构...浑浑噩噩跟同学落了1—2个数据结构没看....果然,我是最弱的

二叉查找树,遵守每个点的左儿子小于点小于右儿子。

于是,BST能够支持的操作:

加点(不用说了)

找前驱(小于一个值的最大值)

找后继(大于一个值得最小值)

根据排名找值

根据值找排名。

直接上代码,理解讲解都在注释里(只给各个函数的代码了)

struct tree
{
int ls,rs,size,cnt,val;
}t[maxn]; //以下为加点
//size表示当前节点的子树大小和自己的大小的和,
//cnt表示当前节点代表的数有几个
void add(int now,int val)//now为当前遍历的点的编号,val为点权值
{
t[now].size++;
if(t[now].val==val)
{
t[now].cnt++;//多个相同值得点,不增加点了
return;
}
if(t[now].val>val)
{
if(t[now].ls!=)
{
addedge(t[now].ls,val);
}
else
{
cnt++;
t[cnt].size=;
t[cnt].val=val;
t[cnt].cnt=;
t[now].ls=cnt;
}
}
else
if(t[now].val<val)//根据二叉查找树的性质来插值
{
if(t[now].rs!=)//如果不是叶子节点
{
addedge(t[now].rs,val);//向下寻找叶子节点再插入
}
else
{
cnt++;//cnt为点的编号
t[cnt].size=;//找前驱的东西
t[cnt].val=val;//存值
t[cnt].cnt=;//有几个相同的值
t[now].rs=cnt;//点的编号,右儿子加点
}
}
}
int getqianqu(int now,int val,int ans)
{
if(t[now].val>=val)//如果当前值大于正在被寻找前驱的值
{//那么可以判定:前驱一定是在它的左子树中
if(t[now].ls==)//如果没有左子树
{
return ans;//当前值就是答案
}
else //否则
{
getqianqu(t[now].ls,val,ans);//在左子树中找答案
}
}
else if(t[now].val<val)//如果当前值小于正在被寻找前驱的值
{//那么可以判定:前驱一定在它的右子树中 ,一路小过来,小过了,往大值试探
if(t[now].rs==)//如果没有右子树
{
if(t[now].val<val)//如果当前值小于正在被寻找前驱的值
{
return t[now].val;//在没有右子树的情况下,当前点就是前驱
}
else
{
return ans;//否则前面点就是前驱
}
}
if(t[now].cnt!=)//删点之后..在treap里的操作,这里没有
{
return getqianqu(t[now].rs,val,t[now].val);
}
else
{
return getqianqu(t[now].rs,val,ans);
}
}
}
int gethouji(int now,int val,int ans)
{
if(t[now].val<=val)//如果当前值大于正在被寻找前驱的值
{
if(t[now].rs==)//如果没有左儿子
{
return ans;
}
else
{
gethouji(t[now].rs,val,ans);
}
}
else if(t[now].val>val)
{
if(t[now].ls==)
{
if(t[now].val>val)
{
return t[now].val;
}
else
{
return ans;
}
}
if(t[now].cnt!=)
{
return gethouji(t[now].ls,val,t[now].val);
}
else
{
return gethouji(t[now].ls,val,ans);
}
}
}
//size表示当前节点的子树大小和自己的大小的和,
//cnt表示当前节点代表的数有几个
int nth(int now,int rank)
{
if(now==)//0,没有值
{
return 0x7fffffff;
}
if(t[t[now].ls].size>rank)//如果左子树的子树的大小大于nth
{
return nth(t[now].ls,rank);//去找左子树
}
if(t[t[now].ls].size+t[now].cnt>=rank)//如果左子树的子树的大小+当前节点(重复节点)大于等于nth
{
return t[now].val;//那这个点就是nth
}
return nth(t[now].rs,rank-t[t[now].ls].size-t[now].cnt);//找子树中nth-子树大小的值
}
int valth(int now,int val)
{
if(now)==)
{
return ;
}
if(val==t[now].val)
{
return t[t[now].ls].size+;
}
if(val<t[now].val)
{
return valth(t[now].ls,val);
}
return valth(t[now].rs,val)+t[t[now].ls].size+t[now].cnt;
}//基本同理于kth

(完)

最新文章

  1. .NET Core系列 : 2 、project.json 这葫芦里卖的什么药
  2. CozyRSS开发记录2-酷炫的皮肤库
  3. XCode6 生成prefix.pch文件
  4. Andrew Ng机器学习公开课笔记 -- Regularization and Model Selection
  5. object
  6. ifram一些常用的知识点
  7. iOS类初始化
  8. JavaScript 数据类型转换(显式与隐式)
  9. cocos2d安装配置及打包成Android
  10. Lombok 使用小结
  11. I/O模型
  12. DOM知识点总结
  13. chrome截图全网页
  14. 怎样在win7 IIS中部署网站
  15. C++ 非常量引用无效
  16. 学习笔记43—Linux基础集
  17. 在html5 canvas的destination-atop属性的一些奇怪的问题
  18. WebAPI 消息处理器
  19. es 加磁盘扩容
  20. PHP-从零开始使用Solr搜索引擎服务(上)

热门文章

  1. Executor线程池原理详解
  2. Node.js入门教程 第五篇 (Express框架)
  3. 刨ThreadLocal的坟
  4. 算法学习之剑指offer(二)
  5. cocos2d-x 3.2,Label,Action,Listener,Menu Item等简单用法
  6. Linux快速入门
  7. Spring Boot Actuator 整合 Prometheus
  8. 真——Springcloud支持Https
  9. 【Spring Cloud】全家桶介绍(一)
  10. MFC::使用mysql