数据结构小笔记-BST、AVL、Splay-Tree、B-Tree、R&B-Tree、Hash Table

20220428

教材:算法导论、具体数学、数据结构与算法分析。

递归:减而治之 or 分而治之。

迭代:

ADT = “说明书”。

Pavlov said his dogs are male forever.

20220429:

插值查找 = 查字典

Pavlov is more niubi than Freud.

20220502:

树 = List<List> = (List)^2

20220503:

树 = 无环有向连通图

二叉树 = 有根有序树

无向图 = 双向边有向图

网络 = 带权有向图

20220504:

Graph(非线性)→ Tree(半线性)→ Sepuence(线性)

Graph的遍历过程 = 搜索(search)

图广度优先搜索(Breadth-First Search, BFS)(Queue) = 树层次遍历的推广

图深度优先搜索(Depth-First Search, DFS)(Stack)

优先级搜索(PFS)

MST(minimum spanning tree):shortest bridge 有时不唯一,所以MST有时也不唯一。

20220507:

BST(二叉搜索树):局部有序性,全局单调性。

BBST(渐近和适度平衡意义下):平衡二叉搜索树(包括AVL、R/B等,参考《算导CLRS》第13章章末注记)。

CBT(理想平衡意义下):完全二叉树

CBT ∈ BBST ∈ BST

BST = Vector + List

BST:node~entry~key(赛车手~赛车~车牌号)

词条模板类Entry = <key, value> pair

20220508:

AVL:平衡因子,树高度。

zig = 顺时针旋转:左分支更深,左下向右上。此时的再平衡旋转叫zig。

zag = 逆时针旋转:右分支更深,右下向左上。此时的再平衡旋转叫zag。

zigzig:(顺时针旋转两次)(从叶向根)左下向右上、再向右上。

zagzag:(逆时针旋转两次)(从叶向根)右下向左上、再向左上。

zigzag:(先顺时针旋转、再逆时针旋转)(从叶向根)左下向右上、再向左上。

zagzig:(先逆时针旋转、再顺时针旋转)(从叶向根)右下向左上、再向右上。

AVL(3+4)-重构:(最低失衡节点至少是动态操作节点的上三代,把爷父孙三代中序遍历,得到)3个节点与4个子树。

AVL(3+4)-重构 = 简化zig、zag等旋转操作。

伸展树(Splay-Tree):没有平衡因子之类指标,不需额外封装。

R/B:动态重平衡后,全树拓扑结构变化量稳定在O(1)。

(AVL全树拓扑结构变化量,insert=O(1),remove=O(logn))。

高级数据结构和算法,对【全树拓扑结构变化量】有严格要求。

Splay-Tree(宽松平衡意义下):伸展树(∈ BST)。每访问一个节点,便将该节点旋转为根节点。

Splay-Tree的zig-zig和zag-zag,与AVL重平衡的zig-zig和zag-zag,效果相同;

AVL重平衡的zig-zag或zag-zig:从孙到爷,父先旋转、爷再旋转(自下而上)。

Splay-Tree双层伸展的zig-zag或zag-zig:从爷到孙,爷先旋转、父再旋转(自上而下)(Tarjan,1985)。可缩小全树高度,使最坏情况的时间复杂度为O(logn)。

B-树:实现数据的高效I/O。不属于BST,但逻辑上等效于BST。

磁盘访问速度 ms级;内存访问速度 ns级,至少相距100000倍。

I:低层存储器把数据读入(输入)高层。O:高层存储器把数据写到(输出)低层。

I/O:输入/输出。

20220509:

B-Tree:(Bayer)
(叶节点深度相同)理想平衡,比BBST更宽更矮(矮胖);
动态调整拓扑结构;
B-Tree = 多路平衡搜索树 = (多代合并的)BBST;
(优点)多代合并而成的超级节点,可批量访问外存.

m路B-Tree = m阶B-Tree = ([m/2],m)-Tree
m = 超级节点的最大分支数。
n = 超级节点的最大合并节点数(该超级节点的关键码key的最多个数)。
m = n+1.
[ ] = 向上取整。

(2,4)-Tree 与 RB-Tree 有关。

B-Tree的查找 = 内存中的Vector顺序查找 与 I/O操作 间隔进行。每次只读入必需节点,尽可能减少I/O操作。

外部节点:将存放于不同存储级别上的B-Tree们串接起来。

为让每次I/O操作的延迟时长(内存访问的100000倍)更划算,每个超级节点的大小应尽量与一次I/O交换页面的大小相匹配。一次I/O操作的交换页面大小通常为几Kb,每个关键码key大小通常为4Byte,因此 1Kb 对应 200-300个key,每个超级节点大致有几百个key(几百个合并节点)。

B-Tree的高度h = 最低层虚拟的外部接口的高度h。
B-Tree的h 比BBST 多算一层。

每查找一次,都只有两种结果:成功找到 or 查找失败。
若B-Tree内总共有N个key,则对应N次成功可能,则相应有N+1种失败可能。
N个内部节点,N+1个外部节点。
N种成功可能,N+1种失败可能。

B-Tree高度h增加的唯一情况:Insert新节点(新关键码key)时,发生超级节点的上溢(overflow),该超级节点拆牌后又overflow……一路overflow到根超级节点,根超级节点也overflow、再拆牌形成新的根节点。此时,新的根节点只有一个关键码key、只有2个分支。

insert - overflow - 拆牌分裂
remove - underflow - 合并

B-Tree高度h减少的唯一情况:remove某关键码key1时,先找到key1的直接后继(先取key1的右分支超级节点,取该超级节点最左端的关键码key2、即该超级节点向量的第一个元素;再取key2的左分支,取该左分支超级节点最左端的关键码key3……重复上述找左分支的操作,直至 叶超级节点,该叶超级节点的最左端关键码即key1的直接后继),交换key1及其直接后继。此时key1在某叶超级节点内,remove key1之后,该叶超级节点可能underflow(n < [m/2]-1,此处[ ]为向上取整),此时该叶超级节点的节点数 n = [m/2]-2。在该叶超级节点处,左顾右盼,若其左右兄弟超级节点不存在、或其左右兄弟超级节点的节点数=[m/2]-1,则无法用“旋转”操作来满足B-Tree超级节点内的节点数n的取值范围([m/2]-1 <= n <= m-1),此时改用“合并”操作。“合并”操作会从key1所在叶超级节点的parent超级节点中取走一个key,因此该parent超级节点也可能underflow,重复上述“无法旋转、改用合并”的过程,直至 根超级节点。碰巧,根超级节点只有一个关键码key、只有2个分支,“合并”后,该 根超级节点没有key、只有一个分支,以这一分支为新的根超级节点,此时B-Tree高度减少为h-1.

B-Tree 水平方向上,是在内存RAM中搜索,速度快、耗时少;
B-Tree 垂直方向上,是在磁盘DISK中进行I/O操作,速度慢、耗时多(单次I/O耗时是RAM的100000倍)。
为平衡RAM与DISK之间的整体耗时,应尽量多在水平方向上搜索,尽量少在垂直方向上I/O,所以B-Tree“矮胖”。

20220510:

R&B-Tree:一种BBST,其中任何一次动态操作(insert、remove)引发的树形拓扑结构变化 不超过 O(1),即任何一次insert或remove都只引发常数次“旋转”(zig+zag双旋(即(3+4)-重构),或zig/zag单旋)。

R&B-Tree == half-BBST ∈ BBST
各红节点均提升一层(类似二代合并)之后的R&B-Tree == (2,4)-Tree == 某一种B-Tree

(1)为保证是真二叉树,提前为R&B-Tree的每个叶节点增加1或2个虚拟的黑外部节点;
(2)黑帽(根节点为黑)黑鞋(外部节点为黑);
(3)红节点上下 只领接 黑节点——保证树的高度;
(4)任一黑外部节点 到 根节点 的唯一路径上,黑节点数目相等——因此,路径上的各红节点均提升一层(类似二代合并)后,任一底层黑外部节点的高度 H 均相等,即叶节点等高平齐——保证树的左右平衡性。

R&B-Tree的高度h 代码实现时一般是指 黑高度H。
h <= 2H,因为红节点上下只领接黑节点,任一叶根路径上的红节点均不多于黑节点,所以任一叶根路径上 红+黑 <= 2*黑,即h <= 2H。

R&B-Tree ->(lifting)-> (2,4)-B-Tree

R&B-Tree insert操作的RedRed缺陷:
爷孙三代red lifting(类似二代合并)之后,依uncle节点的黑或红而有2种情况——
(1)若uncle节点为黑,(3+4)-重构(或zig、zag)之后,重染色O(1)次,局部拓扑结构改变O(1)次;
(2)若uncle节点为红,此时red lifting后、对应的(2,4)-B-Tree发生overflow,并 可能 向根节点传递发生多次overflow(某层发生一次overflow,该层需重染色一次;最坏情况(有logn层)发生logn次overflow),则重染色至多O(logn)次,局部拓扑结构改变0次。

R&B-Tree单次insert,至多只发生一次(3+4)-重构,即局部拓扑结构只改变一次,这有利于persistent structures(持久化结构,便于记忆 树的时间轴版本,详见计算几何)。

R&B-Tree remove操作的BlackBlack缺陷:
某路 上下两代节点均为黑,remove之后,对应的(2,4)-B-Tree发生underflow。

【BB-1】 —— R&B-Tree ->(lifting)-> (2,4)-B-Tree,remove后为下溢节点,(3+4)-重构一次(或zig+zag双旋一次),以sibling节点为新的爷节点,重染色1或2次。

【BB-2R】 —— R&B-Tree ->(lifting)-> (2,4)-B-Tree,remove后为下溢节点,无法zig/zag旋转,改用“合并”,重染色2次,局部拓扑结构改变0次。

【BB-2B】(局部全黑)—— R&B-Tree ->(lifting)-> (2,4)-B-Tree,remove后为下溢节点,无法zig/zag旋转,改用“合并”,重染色1次(sibling节点由黑染红),合并后的(2,4)-B-Tree发生上层的underflow、并 可能 向根节点传递发生O(logn)次underflow。因此,对应的R&B-Tree至多重染色O(logn)次,局部拓扑结构改变0次。

【BB-3】 —— R&B-Tree ->(lifting)-> (2,4)-B-Tree,remove后为下溢节点,zig/zag单旋一次,重染色2次(sibling节点由红染黑,parent节点由黑染红),(2,4)-B-Tree -> R&B-Tree,局部拓扑结构改变一次。此时(parent节点已染红),已转化为BB-1或BB-2R(若转化为BB-2R,则局部拓扑结构还需改变一次;因此,BB-3总计改变局部拓扑结构1或2次)。

R&B-Tree的remove操作,至多只需O(logn)次recoloring、以及1或2次局部拓扑结构改变(在persistent structures方面至关重要),这一特点优于AVL的remove操作。

20220511
散列(Hash):

call-by-rank(下标):Vector
call-by-position(地址):List
call-by-key(关键码):BST
call-by-value(访问对象本身):Hash

在巨大数据空间(词条空间)里,只存储和组织非常少的数据(hash table地址空间),例如电话簿、词典等。若直接用数组(array),则空间效率极低,可将array改进为Hash。

array中的每个单元 == Hash中的桶单元(bucket)
array == 桶数组(bucket array) == 散列表(hash table)

关键:适当选取Hash table的长度M,M大小最好同阶于(非常少的)真正存储和组织的数据量。

Hash table适当压缩 巨大数据空间(词条空间)。

定址 == 杂凑 == 散列 == Hashing:确定 目标词条 位置的过程,可用 散列函数(hash function)【hash():key -> &entry】。

Hashing:key -> hash(key) -> bucket/&entry -> entry -> 目标词条。

电话号码(key) -> hash(key)=key%M -> 机主信息(bucket):
时间复杂度 O(1),
空间复杂度 == 装填因子(load factor) == N/M 大大提高。

hash function 把 巨大词条空间 压缩为 非常小的hash table地址空间(空间大小为M),O(domain) >> O(image),难以实现one-to-one,极易出现“多对一”冲突。

蝉的哲学:蝉有不同变种,但每一变种的生命周期都是 素数。这样的进化,保证蝉与各种天敌(螳螂、黄雀等等)的生命周期的最大公因子都是 1 ;保证在蝉的生命周期内,各种天敌尽可能均匀出现(均匀性,遍历 蝉的全生命周期),不致于在某一年集中出现(Locality,clustering),把某一种蝉一次性吃完、使这一种蝉灭绝。

所以,hash table地址空间的大小M应为素数。

Geometric Computing 对高维数据进行降维压缩时,也可用Hash table,但却是 Locality-Sensitive Hashing:需要保证 邻近的key 依旧被mapping到 邻近的hash地址,这时无需高阶均匀性、甚至一般的零阶均匀性。

Hash(散列): 大空间 -> 小空间(压缩)。
cryptology(密码学): 大空间 <- 小空间。

Hash function:越随机、越没规律,就越好(为保证 关键码key的各位数字 对 散列地址 的影响力尽可能满足 均匀性)。

Hash:key -> hashcode -> (hash function()) -> bucket addr. -> entry

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值