二叉查找树学习笔记(BST)
我土了....终于开始看平衡树了,以前因为害怕一直不敢看数据结构...浑浑噩噩跟同学落了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
(完)
二叉查找树学习笔记(BST)的更多相关文章
- BST,Splay平衡树学习笔记
BST,Splay平衡树学习笔记 1.二叉查找树BST BST是一种二叉树形结构,其特点就在于:每一个非叶子结点的值都大于他的左子树中的任意一个值,并都小于他的右子树中的任意一个值. 2.BST的用处 ...
- 「学习笔记」Treap
「学习笔记」Treap 前言 什么是 Treap ? 二叉搜索树 (Binary Search Tree/Binary Sort Tree/BST) 基础定义 查找元素 插入元素 删除元素 查找后继 ...
- Treap-平衡树学习笔记
平衡树-Treap学习笔记 最近刚学了Treap 发现这种数据结构真的是--妙啊妙啊~~ 咳咳.... 所以发一发博客,也是为了加深蒟蒻自己的理解 顺便帮助一下各位小伙伴们 切入正题 Treap的结构 ...
- 平衡树splay学习笔记#2
讲一下另外的所有操作(指的是普通平衡树中的其他操作) 前一篇的学习笔记连接:[传送门],结尾会带上完整的代码. 操作1,pushup操作 之前学习过线段树,都知道子节点的信息需要更新到父亲节点上. 因 ...
- 《it项目管理那些事》学习笔记
此书适合:计算及相关专业的学生,想成为测试工程师.软件工程师.进入项目经理的人,或者经验丰富的it经理人. 之所以称为学习笔记,是加上我从百度搜到一些在看书过程中不明白的it语,作为菜鸟的我,得多看看 ...
- [学习笔记]平衡树(Splay)——旋转的灵魂舞蹈家
1.简介 首先要知道什么是二叉查找树. 这是一棵二叉树,每个节点最多有一个左儿子,一个右儿子. 它能支持查找功能. 具体来说,每个儿子有一个权值,保证一个节点的左儿子权值小于这个节点,右儿子权值大于这 ...
- 23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge
23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge 2016-07-22 (www.cnblogs.com/icmzn) 模式理解
- 23 DesignPatterns学习笔记:C++语言实现 --- 1.1 Factory
23 DesignPatterns学习笔记:C++语言实现 --- 1.1 Factory 2016-07-18 13:03:43 模式理解
- LinkCutTree学习笔记
LinkCutTree 学习笔记 参考来源 https://www.zybuluo.com/xzyxzy/note/1027479 https://www.cnblogs.com/zhoushuyu/ ...
随机推荐
- asp.net core过滤器记录响应对象
百度到的基本上就是读取response.body的流.然后记录完了之后,把流的index重新复位,这样也太麻烦了. 其实asp.net core团队肯定已经考虑到了这种需求,比如记录请求响应日志.给响 ...
- php实现商城秒杀
这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...
- Web高性能动画及渲染原理(1)CSS动画和JS动画
目录 一. CSS动画 和 JS动画 1.1 CSS动画 1.2 JS动画 1.3 小结 二. 使用Velocity.js实现动画 示例代码托管在:http://www.github.com/dash ...
- Java Intellij 第一个HelloWord
前言 最近重心点都在Java, 鉴于避免一些跟我一样学习Java开始啥都不懂,不知如何下手,方便小白快速入门.故写下此文,鉴于分享. (前提是安装jdk, 建议使用版本是1.8) JDK 安装地址:h ...
- java的动手动脑10月20日
(1)动手动脑 该函数没有赋初值再就是如果类提供一个自定义的构造方法,将导致系统不在提供默认的构造方法. (2) public class test { /*** @param args*/publi ...
- Java 面试-即时编译( JIT )
当我们在写代码时,一个方法内部的行数自然是越少越好,这样逻辑清晰.方便阅读,其实好处远不止如此,通过即时编译,甚至可以提高执行时的性能,今天就让我们好好来了解一下其中的原理. 简介 当 JVM 的初始 ...
- Java ThreadLocal 的使用与源码解析
GitHub Page: http://blog.cloudli.top/posts/Java-ThreadLocal-的使用与源码解析/ ThreadLocal 主要解决的是每个线程绑定自己的值,可 ...
- 致远OA_0day批量植Cknife马一步到位
最近各位师傅都在刷这个嘛,原本的exp是上传一个test123456.jsp的命令执行的马子,不过我在试的时候发现替换成C刀一句话出错,原因未知,并且test123456.jsp如果存在的话用原来ex ...
- swap()函数的几种写法及优劣
试用几种方法实现swap函数,比较效率高低. 首先说结果,最快的是赋值交换. 原因分析 gcc开启O2优化后,三个函数的汇编代码一样.是的,除了第一行的文件名,一模一样. 附代码 void swap1 ...
- jmeter-定时器使用
在一般性能测试过程中,往往在前一个请求之后等待一段时间再执行下一个请求,这时会用到定时器. 以下列举常用的3中: 1.固定定时器: 2.