b树

常见数据结构(二)-树(二叉树,红黑树,B树)

醉酒当歌 提交于 2020-05-04 05:56:55
常见数据结构(二)-树(二叉树,红黑树,B树) 标签: algorithms [TOC] 本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程 《Algorithms, Part I》 中的Slides 相关命题的证明可参考 《算法(第4版)》 源码可在 官网 下载,也可以在我的github仓库 algorithms-learning 下载,已经使用maven构建 仓库下载: git clone git@github.com:brianway/algorithms-learning.git Binary Search Tree(二分查找树) 定义:A BST is a binary tree in symmetric order . A binary tree is either: Empty. Two disjoint binary trees (left and right). Symmetric order.Each node has a key, and every node’s key is: Larger than all keys in its left subtree. Smaller than all keys in its right subtree. 在java的实现中,每个节点

为什么数据库用b+树不用b树和红黑树

偶尔善良 提交于 2020-03-27 02:54:40
前几天面试被问到了,没答好,记录一下: 首先说红黑树为什么不行: 1.红黑树必须存在内存里的,数据库表太大了,存不进去。 2.即使你找到了把红黑树存进硬盘的方法,红黑树查找一个节点最多要查logN层,每一层都是一个内存页(虽然你只是想找一个节点,但硬盘必须一次读一个页。。),那么一共logN次IO,伤不起阿! 所以我们必须考虑减少树的层数来减少IO次数从而加快查询、修改数据库效率,b和b+树都符合这样的性质,它们每个节点的孩子都很多(几十~几千),所以整个树的高度可以压的很低。 比如100000000数据,每个节点有1000个孩子,那么log 1000(100000000)<3,3层就足够存了! 先讲下b树和b+树的区别: b树的所有节点都是数据节点,但b+树只有叶子节点是数据节点,非叶子(内部)节点只起导向作用,不存储实际数据。 b+树的所有数据节点都在最下层(叶子节点层),相邻节点有链表相连。 注意磁盘读数据读一个字节和读10个字节和读一页时间相差不大的(因为磁盘查找时间大多数都花在寻道上,旋转基本不费时) 再说b树为什么不如b+树: 1.b树的内部节点都是存储实际数据的,比如一个节点是一个页4096字节,其中每条数据128字节,那么一个节点只能存32个数据项,那么对应的孩子节点数最多为33个,这显然不够用。而b+树内部节点只作为导向作用,只存一个整数就可以,4096/4

C#实现平衡多路查找树(B树)

有些话、适合烂在心里 提交于 2020-03-22 05:59:22
写在前面:搞了SQL Server时间也不短了,对B树的概念也算是比较了解。去网上搜也搜不到用C#或java实现的B树,干脆自己写一个。实现B树的过程中也对很多细节有了更深的了解。 简介 B树是一种为辅助存储设计的一种数据结构,在1970年由R.Bayer和E.mccreight提出。在文件系统和数据库中为了减少IO操作大量被应用。遗憾的是,他们并没有说明为什么取名为B树,但按照B树的性质来说B通常被解释为Balance。在国内通常有说是B-树,其实并不存在B-树,只是由英文B-Tree直译成了B-树。 一个典型的 B树如图1所示。 图1.一个典型的B树 符合如下特征的树才可以称为B树: 根节点如果不是叶节点,则至少需要两颗子树 每个节点中有N个元素,和N+1个指针。每个节点中的元素不得小于最大节点容量的1/2 所有的叶子位于同一层级(这也是为什么叫平衡树) 父节点元素向左的指针必须小于节点元素,向右的指针必须大于节点元素,比如图1中Q的左指针必须小于Q,右指针必须大于Q 为什么要使用B树 在计算机系统中,存储设备一般分为两种,一种为主存(比如说CPU二级缓存,内存等),主存一般由硅制成,速度非常快,但每一个字节的成本往往高于辅助存储设备很多。还有一类是辅助存储(比如硬盘,磁盘等),这种设备通常容量会很大,成本也会低很多,但是存取速度非常的慢,下面我们来看一下最常见的辅存--硬盘。

B树文件系统树

半腔热情 提交于 2020-03-21 00:02:54
3 月,跳不动了?>>> 二叉排序 树或者二叉搜索树 即二叉搜索树: 1. 所有非叶子结点至多拥有两个儿子( Left 和 Right ); 2. 所有结点存储一个关键字; 3. 非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树; 如: 二叉搜索 树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中; 否则,如果查询关键字比结点关键字小,就进入左儿子;如果比结点关键字大,就进入 右儿子;如果左儿子或右儿子的指针为空,则报告找不到相应的关键字; 如果 二叉搜索 树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么 二叉搜索 树的搜索性能逼近二分查找;但它比连续内存空间的二分查找的优点是,改变 二叉搜索 树结构(插入与删除结点)不需要移动大段的内存数据,甚至通常是常数开销; 如: 但 二叉搜索 树在经过多次插入与删除后,有可能导致不同的结构: 右边也是一个 二叉搜索 树 ,但它的搜索性能已经是线性的了;同样的关键字集合有可能导致不同的树结构索引;所以,使用 二叉搜索 树 还要考虑尽可能让 二叉搜索 树 保持左图的结构,和避免右图的结构,也就 是所谓的“平衡”问题; 实际使用的 二叉搜索 树 都是在原 二叉搜索 树 的基础上加上平衡算法,即“平衡二叉树”;如何保持 二叉搜索 树 结点分布均匀的平衡算法是平衡二叉树的关键;平衡算法是一种在

B树,B+树,B*树简介

限于喜欢 提交于 2020-03-17 03:00:15
B树(有些人也叫B-树) 是一种多路搜索树 : 1.定义任意非叶子结点最多只有M个儿子;且M>2; 2.根结点的儿子数为[2, M]; 3.除根结点以外的非叶子结点的儿子数为[M/2, M]; 4.每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字) 5.非叶子结点的关键字个数=指向儿子的指针个数-1; 6.非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1]; 7.非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的 子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树; 8.所有叶子结点位于同一层; 如:(M=3) B树的搜索,从根结点开始,对结点内的关键字(有序)序列进行二分查找,如果 命中则结束,否则进入查询关键字所属范围的儿子结点;重复,直到所对应的儿子指针为 空,或已经是叶子结点; B树的特性: 1.关键字集合分布在整颗树中; 2.任何一个关键字出现且只出现在一个结点中; 3.搜索有可能在非叶子结点结束; 4.其搜索性能等价于在关键字全集内做一次二分查找; 5.自动层次控制; 由于限制了除根结点以外的非叶子结点,至少含有M/2个儿子,确保了结点的至少 利用率,其最底搜索性能为: 其中

【数据结构】查找

风流意气都作罢 提交于 2020-03-11 23:15:00
平均查找长度(ASL, Average Search Length): 在查找过程中,一次查找的长度是指需要比较的关键字次数,而平均查找长度则是所有查找过程中进行关键字比较次数的平均值,(即 ASL= \(\sum\) 查找概率*比较次数 )(一般为等概率1/n) 静态查找表: 查找表的操作无需动态地修改查找表,如 顺序查找、折半查找、散列查找等。 动态查找表: 需要动态地插入或删除的查找表,如 二叉排序树、二叉平衡树、B树、散列查找等。 线性结构 顺序查找 适用条件: 适用于 线性表 基本思想: 从线性表的一段开始,逐个检查关键字是否满足给定的条件。若查找到某个元素的关键字满足给定的条件,则查找成功,返回该元素在线性表中的位置;若已经查找到表的另一端,但还没有查找到符合给定条件的元素,则返回查找失败的信息。 具体实现: typedef struct { //查找表的数据结构 ElemType *data; //元素空间基址,建表时按实际长度分配,0号单元留空 int length; //表的长度 }List; //Sequential Search Table //在顺序表L中顺序查找关键字为key的元素。若找到则返回该元素在表中的位置 int Search_Seq(List L, ElemType key) { L.data[0] = key; //“哨兵” for(i = L

阿里面试官,直接重置了我对索引的了解

元气小坏坏 提交于 2020-03-11 12:59:52
前言 写数据库,我第一时间就想到了MySQL、Oracle、索引、存储过程、查询优化等等。 不知道大家是不是跟我想得一样,我最想写的是索引,为啥呢? 以下这个面试场景,不知道大家熟悉不熟悉: 面试官:数据库有几千万的数据,查询又很慢我们怎么办? 面试者:加索引。 面试官:那索引有哪些数据类型?索引是怎么样的一种结构?哪些字段又适合索引呢?B+的优点?聚合索引和非聚合索引的区别?为什么说索引会降低插入、删除、修改等维护任务的速度?……… 面试者:面试官怎么出我们公司门来着😂。 是的大家可能都知道慢了加索引,那为啥加,在什么字段上加,以及索引的数据结构特点,优点啥的都比较模糊或者甚至不知道。 那我们也不多BB了,直接开始这次的面试吧。 正文 我看你简历上写到了熟悉MySQL数据库以及索引的相关知识,我们就从索引开始,索引有哪些数据结构? Hash、B+ 大家去设计索引的时候,会发现索引类型是可以选择的。 为什么哈希表、完全平衡二叉树、B树、B+树都可以优化查询,为何Mysql独独喜欢B+树? 我先聊一下Hash: 大家可以先看一下下面的动图 注意字段值所对应的数组下标是哈希算法随机算出来的,所以可能出现哈希冲突。 那么对于这样一个索引结构,现在来执行下面的sql语句: select * from sanguo where name=‘鸡蛋’ 可以直接对‘鸡蛋

数据结构——B树、B+树、B*树

余生长醉 提交于 2020-03-11 01:36:00
目录 (一)B树(B-树) 1、二叉搜索树 2、B树的基本概念 3、m阶B树的性质 4、B树和二叉树的操作比较 (二)B+树 1、B+树的基本概念 2、B+树的特征 3、B+的优势 (三)B*树 1、B*树的基本概念 2、B*树特点 (一)B树(B-树) 1、二叉搜索树   二叉搜索树有如下特点: 所有非叶子结点至多拥有两个孩子(Left和Right) 所有结点存储一个关键字 非叶子节点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树   二叉树的搜索,从根节点开始若查询的关键字与节点关键字相等则命中;否则若关键字比结点关键字小则进入左孩子;如果比结点关键字大,就进入右孩子;若左孩子或有孩子的指针为空,则报告未找到该关键字。 2、B树的基本概念   B树(一种多路搜索树,不一定是二叉)的出现是因为磁盘 IO ,IO操作的效率很低,在大量数据存储中(一般用于数据库索引,查找效率较高),查询时我们不能一下将所有数据都加载到内存中,只能逐一加载磁盘页,每个磁盘页对应树的结点。造成大量磁盘 IO 操作(最坏情况下为树的高度),平衡二叉树由于树的深度过大造成磁盘 IO读写频繁所耗费时间长,导致效率低 。       &   磁盘 IO 与预读 emsp; 磁盘读取以靠机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加为一次磁盘 IO 的时间,大概9ms

B树与B+树简明扼要的区别

自古美人都是妖i 提交于 2020-03-08 00:58:36
看了很多讲B树和B+树的文章,大多都是围绕各自的特性讲的,第一,树中每个结点最多含有m个孩子(m>=2);第二,……我也是从这些文章里弄懂了各种树的联系与区别,要真写,我可能还不如人家写得好。所以就在这里简明扼要的用几张图记录一下主要区别吧。 为了便于说明,我们先定义一条数据记录为一个二元组[key,data],key为记录的键值,key唯一;data为数据记录除key外的数据。 B树 每个节点都存储key和data,所有节点组成这棵树,并且叶子节点指针为null。 B+树 只有叶子节点存储data,叶子节点包含了这棵树的所有键值,叶子节点不存储指针。 后来,在B+树上增加了顺序访问指针,也就是每个叶子节点增加一个指向相邻叶子节点的指针,这样一棵树成了数据库系统实现索引的首选数据结构。 原因有很多,最主要的是这棵树矮胖,呵呵。一般来说,索引很大,往往以索引文件的形式存储的磁盘上,索引查找时产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘I/O操作次数的时间复杂度。树高度越小,I/O次数越少。 那为什么是B+树而不是B树呢,因为它内节点不存储data,这样一个节点就可以存储更多的key。 在MySQL中,最常用的两个存储引擎是MyISAM和InnoDB,它们对索引的实现方式是不同的。 MyISAM

b树,以及b+树的构建,以及mysql底层索引的原理

 ̄綄美尐妖づ 提交于 2020-03-05 18:07:56
B-Tree: M阶的Btree的几个重要特性: 1.节点最多含有m颗子树(指针),m-1个关键字(数据)(m>=2); 2.除根节点和叶子节点外,其他每个节点至少有ceil(m/2)个子结点(子树),ceil为向上取整,5/2=3取整,分裂的时候从中间分开,分成两个子树 3.若根节点不是叶子节点,则至少有两颗子树。 Btree有个非常重要的操作:当一颗树不满足以上性质的时候会干嘛?红黑树大家已经知道了会左旋右旋变颜色。而是 Btree的分裂。 分裂过程如图: b树减少了磁盘IO的,增加了查询效率。最重要的是分裂过程构建b树。 缺点是:不能解决范围查询,以及所有点都存数据造成空间浪费,所以MySQL最终选择了b+树 b+树: b+树的3个性质: 1.叶子结点通过双向链表连接 2.非叶子结点不存放数据 3.数据和节点一样多 通过图可以看出b+树和b树的区别: MySQL底层索引: MySQL底层索引就是采用b+树的结构,大量减少磁盘IO次数,充分存储了数据。 通过双向链表解决了索引的范围查询 节点存储多个索引,符合了联合索引的左原则。 通过索引关键字的个数及大小,以及页面大小(一次IO查询的数据量),可以计算b+树的阶数 b+树的特点总结: 总结: 来源: CSDN 作者: FunnySour 链接: https://blog.csdn.net/qq_36767214/article