数据结构与算法之 B 树 数据中台 索引中心 / 范围查询服务 构建

数据结构与算法阿木 发布于 20 天前 5 次阅读


B 树:数据中台(索引中心 / 范围查询服务)构建技术解析

在数据中台的建设中,索引中心与范围查询服务是至关重要的组成部分。B 树作为一种平衡的多路查找树,因其高效的插入、删除和查找性能,被广泛应用于数据库索引、文件系统等领域。本文将围绕 B 树的数据结构与算法,探讨其在数据中台(索引中心 / 范围查询服务)构建中的应用。

B 树概述

B 树是一种自平衡的树,它能够将数据元素组织成一种层次结构,使得数据的插入、删除和查找操作都能在 O(log n) 的时间复杂度内完成。B 树的特点如下:

1. 树中每个节点包含一个或多个键值,以及指向子节点的指针。

2. 树中每个节点最多包含 m 个键值,其中 m 是一个固定的整数,称为 B 树的阶。

3. 树中每个节点(根节点除外)至少包含 m/2 个键值。

4. 树的根节点至少包含 2 个键值。

5. 所有叶子节点都在同一层,且不包含任何键值。

B 树的数据结构

以下是一个简单的 B 树节点数据结构示例:

python

class BTreeNode:


def __init__(self, leaf=False):


self.leaf = leaf


self.keys = []


self.children = []

def is_full(self):


return len(self.keys) == 2 self.t - 1

def is_empty(self):


return len(self.keys) == 0


其中,`t` 表示 B 树的阶,`leaf` 表示节点是否为叶子节点,`keys` 存储节点的键值,`children` 存储指向子节点的指针。

B 树的插入操作

B 树的插入操作分为以下步骤:

1. 如果根节点为空,则创建一个新的根节点。

2. 如果根节点非空,则将新键值插入到根节点中。

3. 如果根节点已满,则创建一个新的根节点,并将原根节点作为新根节点的一个子节点。

4. 从根节点开始,沿着路径向下查找插入位置。

5. 如果当前节点未满,则将新键值插入到该节点中。

6. 如果当前节点已满,则进行节点分裂操作。

以下是一个简单的 B 树插入操作示例:

python

def insert_non_full(node, key):


i = len(node.keys) - 1


if node.is_empty():


node.keys.append(key)


else:


while i >= 0 and key < node.keys[i]:


i -= 1


i += 1


if node.is_full():


split_node(node, i)


if key > node.keys[i]:


i += 1


node.keys.insert(i, key)

def split_node(node, i):


t = len(node.keys) // 2


right_child = BTreeNode(leaf=node.leaf)


node.keys = node.keys[:t]


right_child.keys = node.keys[t:]


node.children = node.children[:t + 1]


right_child.children = node.children[t + 1:]


node.keys.append(right_child.keys[0])


node.children.append(right_child)


B 树的删除操作

B 树的删除操作分为以下步骤:

1. 从根节点开始,沿着路径向下查找要删除的键值。

2. 如果找到要删除的键值,则进行删除操作。

3. 如果删除操作导致节点不满足 B 树的性质,则进行节点合并或节点提升操作。

以下是一个简单的 B 树删除操作示例:

python

def delete_key(node, key):


i = 0


while i < len(node.keys) and key > node.keys[i]:


i += 1


if i < len(node.keys) and key == node.keys[i]:


delete_from_leaf(node, i)


elif node.leaf:


raise ValueError("Key not found")


else:


delete_from_non_leaf(node, i)

def delete_from_leaf(node, i):


del node.keys[i]


del node.children[i]

def delete_from_non_leaf(node, i):


j = i + 1


while j < len(node.keys) and node.children[j].is_empty():


j += 1


if j < len(node.keys):


borrow_from_right(node, i)


elif i > 0:


borrow_from_left(node, i)


else:


merge_with_left(node, i)


delete_from_leaf(node.children[i], 0)

def borrow_from_right(node, i):


right_child = node.children[i + 1]


node.keys[i] = node.children[i].keys.pop()


node.children[i].keys.append(right_child.keys.pop(0))


node.children[i].children.append(right_child.children.pop(0))

def borrow_from_left(node, i):


left_child = node.children[i - 1]


node.keys[i] = left_child.keys.pop()


right_child = node.children[i + 1]


left_child.keys.append(right_child.keys.pop(0))


left_child.children.append(right_child.children.pop(0))

def merge_with_left(node, i):


left_child = node.children[i - 1]


right_child = node.children[i + 1]


left_child.keys.append(node.keys[i])


left_child.keys.extend(right_child.keys)


left_child.children.extend(right_child.children)


del node.children[i]


del node.children[i + 1]


del node.keys[i]


B 树的范围查询

B 树的范围查询是指查找所有在给定区间 [low, high] 内的键值。以下是一个简单的 B 树范围查询示例:

python

def range_query(node, low, high):


result = []


if node.leaf:


for key in node.keys:


if low <= key <= high:


result.append(key)


else:


for i in range(len(node.keys)):


if low <= node.keys[i] <= high:


result.extend(range_query(node.children[i], low, high))


elif low > node.keys[i]:


result.extend(range_query(node.children[i + 1], low, high))


return result


总结

B 树作为一种高效的数据结构,在数据中台(索引中心 / 范围查询服务)构建中具有广泛的应用。本文介绍了 B 树的数据结构、插入操作、删除操作和范围查询,为读者提供了 B 树在数据中台构建中的技术解析。在实际应用中,可以根据具体需求对 B 树进行优化和改进,以满足更高的性能要求。