平衡树前传之BST

二叉查找树(\(BST\)),是一个类似于堆的数据结构,

并且,它也是平衡树的基础.

因此,让我们来了解一下二叉查找树吧.

(其实本篇是作为放在平衡树前的前置知识的,但为了避免重复懒得写就单独拎了出来)

首先,二叉查找树,是一个树形的数据结构废话,树上的每个节点有一个权值\(val\).

而树中的任意一个节点,都满足以下性质:

  1. 该节点的权值不小于它左子树中任意节点的权值.

  2. 该节点的权值不大于它右子树中任意节点的权值.

显然,二叉查找树的中序遍历就是一个递增序列.

那么接下来,让我们了解\(BST\)的操作吧.

step 1:BST的建立

其实这个很简单,就是为了避免越界而插入\(INF\)和\(-INF\)而已.

看代码吧(是不是好简单):

struct BST{int l,r,val;}t[100001];
int tot=0,rt/*根节点*/,INF=1<<30; inline int New(int val){
t[++tot].val=val;
return tot;
} inline void build(){
New(-INF);New(INF);
rt=1;t[1].r=2;
}

step 2:BST的查找

查找也很好理解.

假设我们要查找的是权值\(v\),

那么根据两条性质,

若\(v\)小于当前节点的权值,就往左走,否则就往又走.

相等或者是空节点(即没有)时,就返回.

上代码(应该很好想吧):

int find(int p,int val){
if(!p||t[p].val==val) return p;
return find(val<t[p].val? t[p].l:t[p].r,val);
}

step 3:BST的插入

shanchu其实这和查找的想法一样.

插入时,若已经插入过,就直接返回(或根据题目情况而定),

到空节点时,就新建节点.

step 4:BST求前驱&后继

就拿前驱为例子吧(因为道理是一样的).

首先,我们先去找要求的点\(p\),

那么有几种情况:

  1. 没有找到\(p\).
  2. 找到了\(p\),但\(p\)无左子树.
  3. 找到了\(p\),且\(p\)有左子树.

对于第一种情况,答案就在寻找过的路径中.

因为如果要插入\(p\)的话,它肯定在它前驱的右子树中(模拟一下插入就知道了).

而第二种情况,由于没有左子树,因此答案也在之前的路径中.

第三种的话,我们先找到它的左子树,再一直往右走,就能找到了(根据BST的性质仔细想想就能理解了).

来上代码吧:

inline int getpre(int val){
int ans=1,p=rt;//t[1].val=-INF
while(p){
if(val==t[p].val){
if(!t[p].l) return ans;
p=t[p].l;
while(t[p].r) p=t[p].r;
return p;
}
if(t[p].val<val&&t[p].val>t[ans].val) ans=p;
p=val<t[p].val? t[p].l:t[p].r;
}
return ans;
}

step 5:BST的删除

删除就要复杂一些了qwq.

如果是空节点,就直接返回.(先排除掉一种情况)

那么假设我们找到了要删除的点,

还有三种情况:

  1. \(p\)为叶子节点.
  2. \(p\)无左/右子树.
  3. \(p\)有左/右子树.

对于第一种,直接删掉就好.

而第二种的话,就可以用子节点代替它.

第三种有点难想啊...

其实,我们可以找出它的前驱/后继节点(就是上一步的第三种情况).

然后再代替它就行啦.

来上代码吧:

inline void remove(int &p,int val){
if(!p) return ;
if(val==t[p].val){
if(!t[p].l) p=t[p].r;
else if(!t[p].r) p=t[p].l;
else {
int next=t[p].r;
while(t[p].l) p=t[p].l;
remove(t[p].r,t[next].val);
t[next].l=t[p].l;t[next].r=t[p].r;
p=next;
}
return ;
}
remove(val<t[p].val? t[p].l:t[p].r,val);
}

总结

BST的几个操作都讲完啦!

然而,发现一件事没?

如果我们依次插入一个递增/递减序列,BST就会被卡成一条链.

因此,我们有了平衡树...

[学习笔记] 二叉查找树/BST的更多相关文章

  1. 二叉查找树学习笔记(BST)

    我土了....终于开始看平衡树了,以前因为害怕一直不敢看数据结构...浑浑噩噩跟同学落了1—2个数据结构没看....果然,我是最弱的 二叉查找树,遵守每个点的左儿子小于点小于右儿子. 于是,BST能够 ...

  2. BST,Splay平衡树学习笔记

    BST,Splay平衡树学习笔记 1.二叉查找树BST BST是一种二叉树形结构,其特点就在于:每一个非叶子结点的值都大于他的左子树中的任意一个值,并都小于他的右子树中的任意一个值. 2.BST的用处 ...

  3. 【数据结构与算法Python版学习笔记】树——二叉查找树 Binary Search Tree

    二叉搜索树,它是映射的另一种实现 映射抽象数据类型前面两种实现,它们分别是列表二分搜索和散列表. 操作 Map()新建一个空的映射. put(key, val)往映射中加入一个新的键-值对.如果键已经 ...

  4. 「学习笔记」Treap

    「学习笔记」Treap 前言 什么是 Treap ? 二叉搜索树 (Binary Search Tree/Binary Sort Tree/BST) 基础定义 查找元素 插入元素 删除元素 查找后继 ...

  5. Treap-平衡树学习笔记

    平衡树-Treap学习笔记 最近刚学了Treap 发现这种数据结构真的是--妙啊妙啊~~ 咳咳.... 所以发一发博客,也是为了加深蒟蒻自己的理解 顺便帮助一下各位小伙伴们 切入正题 Treap的结构 ...

  6. 平衡树splay学习笔记#2

    讲一下另外的所有操作(指的是普通平衡树中的其他操作) 前一篇的学习笔记连接:[传送门],结尾会带上完整的代码. 操作1,pushup操作 之前学习过线段树,都知道子节点的信息需要更新到父亲节点上. 因 ...

  7. 《it项目管理那些事》学习笔记

    此书适合:计算及相关专业的学生,想成为测试工程师.软件工程师.进入项目经理的人,或者经验丰富的it经理人. 之所以称为学习笔记,是加上我从百度搜到一些在看书过程中不明白的it语,作为菜鸟的我,得多看看 ...

  8. [学习笔记]平衡树(Splay)——旋转的灵魂舞蹈家

    1.简介 首先要知道什么是二叉查找树. 这是一棵二叉树,每个节点最多有一个左儿子,一个右儿子. 它能支持查找功能. 具体来说,每个儿子有一个权值,保证一个节点的左儿子权值小于这个节点,右儿子权值大于这 ...

  9. 23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge

    23 DesignPatterns学习笔记:C++语言实现 --- 2.1 Bridge 2016-07-22 (www.cnblogs.com/icmzn) 模式理解  

随机推荐

  1. 使用的一些支持swift3.0的开源库

    #解决键盘弹起遮挡工具 pod 'IQKeyboardManagerSwift', '~>4.0.6' #多种类型弹出框 pod 'SCLAlertView', :git => 'http ...

  2. ToLua Timer机制

    从一个Bug说起: 在内部试玩时发现有个任务的玩家跟随Npc逻辑挂了. telnet连接到出问题的设备上, 开始搞事情 这个跟随的逻辑是一个Timer驱动的. 这个Timer在主角创建时就会启动. 一 ...

  3. 忽略警告@SuppressWarnings的用法

    @SuppressWarnings注解用法 @SuppressWarnings注解主要用在取消一些编译器产生的警告对代码左侧行列的遮挡,有时候这会挡住我们断点调试时打的断点. 我们可以在方法上加上@S ...

  4. Jmeter学习笔记(九)——响应断言

    Jmeter中又一个元件叫断言,用于检查测试中得到的响应数据等是否符合预期.断言又13种,目前在使用过程中使用到的是响应断言. 有时候请求成功了并不代表测试通过,还要看影响返回的内容是否符合预期的结果 ...

  5. Jmeter学习笔记(七)——监听器元件之察看结果树

    在jmeter中,如果我们需要查看请求结果就需要添加查看结果树,这个监听器元件有那些功能呢? 一.察看结果树界面如下 二.察看结果树界面功能说明 1.所有数据写入文件 (1)文件名:可以通过浏览,选择 ...

  6. Python学习资料收集

    1.Learn Python the hard way 2.Google's Python lesson 3.Python最佳实践 4.Full Stack Python 5.explore flas ...

  7. Android笔记(三十九) Android中的数据存储——SQLite(一) create

    SQLite是内置于Android的一款轻量级关系型数据库,她运算速度快,占用资源少,通常只需要几百K的内存就足够了,因而特别适合在移动设备上使用. SQLite不仅支持标准的SQL语法,还遵循数据库 ...

  8. angularcli 第四篇(执行事件)

    目录: 1.按下按钮执行事件 2.按下键盘回车“Enter”执行事件 1.按下按钮执行事件:<button  (click) = 'setName()'>......</button ...

  9. [daily][qemu][kvm] 使用qemu/kvm模拟numa节点

    qemu的配置参数又复杂又难用,man手册写的也是非常对付,很多信息都没有. 而且,竟然遗弃掉旧的配置,换用新的配置.不过这也是好事,说明它在发展,我是欢迎的. 唯一的问题是,要经常跟着它一起更新配置 ...

  10. C++Primer第五版 练习8.6答案详解

    重写7.1.1节书店程序(第299页),从文件中读取一个交易记录.将文件名作为一个参数传递给main. 本题所需源文件如下: Sales_data.h文件: #pragma once #include ...