k叉树的性质_索引实现靠的是树,你知道么?

之前朋友在面试的时候被问到了许多关于索引的问题,而索引这个词一直也是我们在开发中最最最常见的,也是很多在进行代码优化的时候会去做的一件事情,所以今天我们来说说面试中关于索引的那点事。

索引

什么是索引?

索引其实是数据库的一种术语,在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。

但是面试的时候一般不会问你索引是什么?而是喜欢去问,为什么要去使用索引,它的底层是怎么实现的?那数据库又应该怎么去优化呢?下面我们就从这三个方面去解释一下这些面试中的要点信息。

索引底层实现

索引的实现通常使用B树及其变种B+树。

B-Tree 是最常用的用于索引的数据结构。因为它们是时间复杂度低, 查找、删除、插入操作都可以可以在对数时间内完成。另外一个重要原因存储在B-Tree中的数据是有序的。

哈希表是另外一种你可能看到用作索引的数据结构-这些索引通常被称为哈希索引。使用哈希索引的原因是,在寻找值时哈希表效率极高。所以,如果使用哈希索引,对于比较字符串是否相等的查询能够极快的检索出的值。

我们以MySQL数据库的索引为例子。

既然说到了索引的实现是通过B树和变种B+树,那我们来说说这个B树和B+树。

B树

我们看个图。图中所示,B树事实上是一种平衡的多叉查找树,也就是说最多可以开m个叉(m>=2),我们称之为m阶b树,我给大家多画一点内容,这也是我专门看视频的时候记录下的一些自己的心得。

e50fd38819fb03f7804cd763596bf609.png

图中其实画的是比较简单的,但是如果说我们画一个三阶的,这个时候就可以是这样子的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是一种空间索引结构,它将二维空间划分为四个象限,每个象限可以再继续划分为四个象限,以此类推,直到达到某个终止条件。 在Java中,可以使用以下代码实现空间索引: 1. 定义QuadTree类 public class QuadTree { private final int MAX_CAPACITY = 4; // 每个节点最大容量 private final int MAX_LEVEL = 5; // 最大深度 private int level; // 当前深度 private List<Point> points; // 当前节点包含的点 private Rectangle boundary; // 当前节点的边界 private QuadTree[] children; // 子节点 public QuadTree(Rectangle boundary, int level) { this.boundary = boundary; this.level = level; points = new ArrayList<>(); children = null; } // 插入点 public boolean insert(Point point) { if (!boundary.contains(point)) { return false; } if (points.size() < MAX_CAPACITY && children == null) { points.add(point); return true; } if (children == null) { split(); } for (QuadTree child : children) { if (child.insert(point)) { return true; } } return false; } // 分裂节点 private void split() { children = new QuadTree[4]; int subWidth = boundary.width / 2; int subHeight = boundary.height / 2; int x = boundary.x; int y = boundary.y; children[0] = new QuadTree(new Rectangle(x + subWidth, y, subWidth, subHeight), level + 1); children[1] = new QuadTree(new Rectangle(x, y, subWidth, subHeight), level + 1); children[2] = new QuadTree(new Rectangle(x, y + subHeight, subWidth, subHeight), level + 1); children[3] = new QuadTree(new Rectangle(x + subWidth, y + subHeight, subWidth, subHeight), level + 1); for (Point point : points) { for (QuadTree child : children) { if (child.insert(point)) { break; } } } points.clear(); } // 查询某个矩形内的点 public List<Point> query(Rectangle range) { List<Point> result = new ArrayList<>(); if (!boundary.intersects(range)) { return result; } for (Point point : points) { if (range.contains(point)) { result.add(point); } } if (children != null) { for (QuadTree child : children) { result.addAll(child.query(range)); } } return result; } } 2. 定义Point和Rectangle类 public class Point { public int x; public int y; public Point(int x, int y) { this.x = x; this.y = y; } } public class Rectangle { public int x; public int y; public int width; public int height; public Rectangle(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } public boolean contains(Point point) { return point.x >= x && point.x <= x + width && point.y >= y && point.y <= y + height; } public boolean intersects(Rectangle range) { return !(range.x > x + width || range.x + range.width < x || range.y > y + height || range.y + range.height < y); } } 3. 使用QuadTree进行空间索引 public class Main { public static void main(String[] args) { QuadTree quadTree = new QuadTree(new Rectangle(0, 0, 100, 100), 0); quadTree.insert(new Point(10, 10)); quadTree.insert(new Point(20, 20)); quadTree.insert(new Point(30, 30)); quadTree.insert(new Point(40, 40)); quadTree.insert(new Point(50, 50)); quadTree.insert(new Point(60, 60)); quadTree.insert(new Point(70, 70)); quadTree.insert(new Point(80, 80)); quadTree.insert(new Point(90, 90)); List<Point> points = quadTree.query(new Rectangle(25, 25, 50, 50)); System.out.println(points); } } 输出结果为:[Point{x=30, y=30}, Point{x=40, y=40}, Point{x=50, y=50}, Point{x=60, y=60}, Point{x=70, y=70}],表示查询到了在矩形(25, 25, 50, 50)内的所有点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值