搞定Simscape Multibody闭环机构仿真:Planar Joint报错?别忘了这个关键‘虚约束’关节
2026/4/28 23:33:25
B_树(B-Tree)是一种自平衡的多路搜索树,广泛用于数据库和文件系统中以高效管理大量数据。以下是关于 m 阶 B_树的完整定义与相关特性:
一个 m 阶 B_树满足以下性质:
示例:对于 4 阶 B_树,每个节点最多有 4 棵子树,最少(非根)有 ⌈4/2⌉ = 2 棵子树;关键字个数范围是 1 到 3。
B_树的查找从根节点开始,按如下步骤进行:
由于 B_树是平衡树,所有叶节点在同一层,因此最坏情况下的查找路径长度为 O(logₘ N),其中 N 是关键字总数,具有良好的时间性能。
B_树主要用于磁盘等外部存储系统的索引结构,原因包括:
# 简化的 B_树节点类示例(Python)classBTreeNode:def__init__(self,m,is_leaf=False):self.max_children=m self.min_keys=(m+1)//2-1# ⌈m/2⌉ - 1self.is_leaf=is_leaf self.keys=[]# 存储关键字self.children=[]# 存储子节点指针defis_full(self):returnlen(self.keys)>=self.max_children-1实现 B_树的插入操作需要遵循其结构特性,确保在插入新关键字后仍保持平衡。当节点的关键字数超过上限(m−1)时,必须进行节点分裂以维持 B_树的性质。
从根节点开始查找插入位置
找到合适的叶节点进行插入
检查是否违反最大关键字限制
节点分裂(Split)过程
假设一个节点有 m 个关键字(已满),需分裂为两个节点:
K[⌈m/2⌉]作为提升关键字(升到父节点);更新父节点或创建新根
当前节点关键字为[10, 20, 30, 40](已满)
[10, 20, 30, 40]→ 中间位置是第 ⌈4/2⌉ = 2 个关键字 → 升级K₂ = 20到父节点
→ 左节点保留[10]
→ 右节点为[30, 40]
→ 原节点变为[20]并拆分为两孩子:
[20] / \ [10] [30, 40]如果原节点是根节点,则此时生成新的根节点[20],树高度加一。
classBTreeNode:def__init__(self,m,is_leaf=True):self.m=m self.is_leaf=is_leaf self.keys=[]self.children=[]defis_full(self):returnlen(self.keys)>=self.m-1defsplit_child(parent,index):m=parent.m full_node=parent.children[index]mid=m//2# 分裂点索引(对于 m=4,mid=2)median_key=full_node.keys[mid]# 创建新节点(右半部分)new_node=BTreeNode(m,is_leaf=full_node.is_leaf)new_node.keys=full_node.keys[mid+1:]ifnotfull_node.is_leaf:new_node.children=full_node.children[mid+1:]# 修改原节点为左半部分left_keys=full_node.keys[:mid]ifnotfull_node.is_leaf:left_children=full_node.children[:mid+1]else:left_children=[]# 提取中间关键字并插入父节点parent.keys.insert(index,median_key)parent.children[index]=BTreeNode(m,is_leaf=full_node.is_leaf)parent.children[index].keys=left_keys parent.children[index].children=left_children parent.children.insert(index+1,new_node)definsert_non_full(node,key):i=len(node.keys)-1ifnode.is_leaf:# 直接插入并排序node.keys.append(None)whilei>=0andkey<node.keys[i]:node.keys[i+1]=node.keys[i]i-=1node.keys[i+1]=keyelse:# 找到子树位置whilei>=0andkey<node.keys[i]:i-=1i+=1child=node.children[i]ifchild.is_full():split_child(node,i)ifkey>node.keys[i]:i+=1insert_non_full(node.children[i],key)defbtree_insert(root,key):ifroot.is_full():# 根节点已满,创建新根m=root.m new_root=BTreeNode(m,False)new_root.children.append(root)split_child(new_root,0)insert_non_full(new_root,key)returnnew_rootelse:insert_non_full(root,key)returnroot