数据结构与算法之美学习笔记:第四十八讲

1、解决问题的前提是定义清楚问题

经过对一些模糊需求进行假设,来限定要解决问题的范围

根据某个值查找数据,好比 select * from use where id=1234;
根据区间值来查询某些数据好比 select * from use where id > 1234 and id < 2345java

性能方面的需求,咱们主要考察时间和空间两方面,也就是执行效率和存储空间

执行效率:我么你但愿经过索引,查询数据的效率尽量的高;
存储空间方面咱们但愿索引不须要消耗太多的内存空间数据库

2、尝试用学过的数据结构解决这个问题

支持快速查询、插入等操做的动态数据结构,咱们已经学过散列表、平衡二叉树、跳表
数据结构

这样看来,跳表是能够解决这个问题,实际上,数据库索引所用到的数据结构跟跳表很是类似,叫作B+树
它是经过跳表演化雇来的,而非跳表性能

3、改造二叉查找树来解决这个问题

一、实现代码

/**
 * 这是 B+ 树非叶子节点的定义。
 *
 * 假设 keywords=[3, 5, 8, 10]
 * 4 个键值将数据分为 5 个区间:(-INF,3), [3,5), [5,8), [8,10), [10,INF)
 * 5 个区间分别对应:children[0]...children[4]
 *
 * m 值是事先计算获得的,计算的依据是让全部信息的大小正好等于页的大小:
 * PAGE_SIZE = (m-1)*4[keywordss 大小]+m*8[children 大小]
 */
public class BPlusTreeNode {
  public static int m = 5; // 5 叉树
  public int[] keywords = new int[m-1]; // 键值,用来划分数据区间
  public BPlusTreeNode[] children = new BPlusTreeNode[m];// 保存子节点指针
}

/**
 * 这是 B+ 树中叶子节点的定义。
 *
 * B+ 树中的叶子节点跟内部结点是不同的,
 * 叶子节点存储的是值,而非区间。
 * 这个定义里,每一个叶子节点存储 3 个数据行的键值及地址信息。
 *
 * k 值是事先计算获得的,计算的依据是让全部信息的大小正好等于页的大小:
 * PAGE_SIZE = k*4[keyw.. 大小]+k*8[dataAd.. 大小]+8[prev 大小]+8[next 大小]
 */
public class BPlusTreeLeafNode {
  public static int k = 3;
  public int[] keywords = new int[k]; // 数据的键值
  public long[] dataAddress = new long[k]; // 数据地址

  public BPlusTreeLeafNode prev; // 这个结点在链表中的前驱结点
  public BPlusTreeLeafNode next; // 这个结点在链表中的后继结点
}

二、实现步骤

三、实现思路

分裂合并spa

四、删除操做的例子

4、总结引伸

一、每一个节点中子节点的个数不能超过m,也不能小于m/2
二、根节点的子节点个数不可超过m/2,这是一个例外
三、M叉树只存储索引,并不真正存储数据,这个有点相似跳表
四、经过链表将叶子阶段串联在一次,这样能够方便区间查询
五、通常状况下,根节点会被存储在内存中,其余节点存储在磁盘中3d

相关文章
相关标签/搜索