B树(或称B-树)是一种适用于外查找的树,它是一种平衡的多叉树。

阶为M的B树具有下列结构特征:

1.树的根或者是一片树叶,或者其儿子数在2和M之间。

2.除根节点外的所有非树叶节点儿子数在┌M/2┐和 M之间。

3.所有的树叶都在相同的高度。

4.节点中包括n个关键字,n+1个指针,一般形式为: (n,P0,K1,P1,K2,P2,…,Kn,Pn)。每个结点中关键字从小到大排列,并且当该结点的孩子是非叶子结点时,该k-1个关键字正好是k个儿子包含的关键字的值域的分划。

对于任意一颗包含n个关键字的M阶B树,高度h满足:

h≤log┌m/2┐((N+1)/2 )+1

当B树的分支因子很大时,可以大大降低树的高度,B树的查找效率非常之高。

搜索B树

搜索B树与搜索二叉查找树的操作很类似,只是在每个节点所做的不是个二叉分支决定,而是根据该节点的子女数所做的多路分支决定。

向B树插入关键字

1.向未满的节点插入关键字

2.向已满的节点添加关键字,需要将节点分裂为两个节点:

分裂一个节点有三种情况:

A:父节点未满

有两种情况,分裂leftchild与分裂middlechild:

B:父节点已满,需要将父节点分裂

有三种情况:

最后,特殊情况,产生新的根:

代码:

class Node(object):
def __init__(self,key):
self.key1=key
self.key2=None
self.left=None
self.middle=None
self.right=None
def isLeaf(self):
return self.left is None and self.middle is None and self.right is None
def isFull(self):
return self.key2 is not None
def hasKey(self,key):
if (self.key1==key) or (self.key2 is not None and self.key2==key):
return True
else:
return False
def getChild(self,key):
if key<self.key1:
return self.left
elif self.key2 is None:
return self.middle
elif key<self.key2:
return self.middle
else:
return self.right
class 2_3_Tree(object):
def __init__(self):
self.root=None
def get(self,key):
if self.root is None:
return None
else:
return self._get(self.root,key)
def _get(self,node,key):
if node is None:
return None
elif node.hasKey(key):
return node
else:
child=node.getChild(key)
return self._get(child,key)
def put(self,key):
if self.root is None:
self.root=Node(key)
else:
pKey,pRef=self._put(self.root,key)
if pKey is not None:
newnode=Node(pKey)
newnode.left=self.root
newnode.middle=pRef
self.root=newnode
def _put(self,node,key):
if node.hasKey(key):
return None,None
elif node.isLeaf():
return self._addtoNode(node,key,None)
else:
child=node.getChild(key)
pKey,pRef=self._put(child,key)
if pKey is None:
return None,None
else:
return self._addtoNode(node,pKey,pRef) def _addtoNode(self,node,key,pRef):
if node.isFull():
return self._splitNode(node,key,pRef)
else:
if key<node.key1:
node.key2=node.key1
node.key1=key
if pRef is not None:
node.right=node.middle
node.middle=pRef
else:
node.key2=key
if pRef is not None:
node.right=Pref
return None,None
def _splitNode(self,node,key,pRef):
newnode=Node(None)
if key<node.key1:
pKey=node.key1
node.key1=key
newnode.key1=node.key2
if pRef is not None:
newnode.left=node.middle
newnode.middle=node.right
node.middle=pRef
elif key<node.key2:
pKey=key
newnode.key1=node.key2
if pRef is not None:
newnode.left=Pref
newnode.middle=node.right
else:
pKey=node.key2
newnode.key1=key
if pRef is not None:
newnode.left=node.right
newnode.middle=pRef
node.key2=None
return pKey,newnode

B树及2-3树的python实现的更多相关文章

  1. 【剑指Offer】树的子结构 解题报告(Python)

    [剑指Offer]树的子结构 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://www.nowcoder.com/ta/coding-interviews 题目 ...

  2. 硬核数据结构,让你从B树理解到B+树

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是周五分布式系统的第八篇文章,核心内容是B+树的原理. 今天的文章是上周B树的延伸,所以新关注的或者是有所遗忘的同学建议先从下方链接回顾 ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. poj 2104 K-th Number (划分树入门 或者 主席树入门)

    题意:给n个数,m次询问,每次询问L到R中第k小的数是哪个 算法1:划分树 #include<cstdio> #include<cstring> #include<alg ...

  5. 从B 树、B+ 树、B* 树谈到R 树

    从B 树.B+ 树.B* 树谈到R 树 作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由 ...

  6. 【BZOJ-3196】二逼平衡树 线段树 + Splay (线段树套平衡树)

    3196: Tyvj 1730 二逼平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2271  Solved: 935[Submit][Stat ...

  7. 【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)

    3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 405  Solved: 137[Submit][Status][Discuss] ...

  8. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  9. 【BZOJ1036】[ZJOI2008]树的统计Count 树链剖分

    [BZOJ1036][ZJOI2008]树的统计Count Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. ...

  10. NOIP 2013 货车运输【Kruskal + 树链剖分 + 线段树 】【倍增】

    NOIP 2013 货车运输[树链剖分] 树链剖分 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在 ...

随机推荐

  1. 你真的会用 SDWebImage?

    SDWebImage作为目前最受欢迎的图片下载第三方框架,使用率很高.但是你真的会用吗?本文接下来将通过例子分析如何合理使用SDWebImage. 使用场景:自定义的UITableViewCell上有 ...

  2. Android(java)学习笔记136:Java类初始化顺序

    Java类中初试化的顺序: 由此得出Java普通类初始化顺序结论: 静态变量 静态初始化块 变量 初始化块 构造器 由此得出Java继承类初始化顺序结论:     1 .继承体系的所有静态成员初始化( ...

  3. sed示例

    引用:http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2856901.html [root@www ~]# sed [-nefr] [动作] 选 ...

  4. [转]ODBC连接ORACLE数据库的设置

    本文转自:http://www.cppblog.com/edog/articles/1420.html 首先安装Oracle,以Oracle 817为例,作为ODBC开发者的客户端,才能使用Oracl ...

  5. [java小笔记] 关于数组内存管理的理解

    数组是大多数编程语言都提供的一种复合结构,如果程序需要多个类型相同的变量时,就可以考虑定义一个数组,java语言的数组变量时引用类型的变量,因此具有java引用变量的特性.在使用数组之前必须对数组对象 ...

  6. SharePoint缓存导致访问慢解决

    产品发布到公网时,客户每次访问页面都很慢,经过查找原因,发现在服务器上的APPFabric缓存出错误了: APPFabric缓存服务作用:用作内存中缓存来存储应用程序访问的数据,从而提高应用程序性能. ...

  7. (原创)openvswitch实验连载1-fedora 17下安装openvswitch

    1 软件安装 1.1测试环境和网络拓朴 大部分朋友估计也没有一个真实环境来完全整个的测试,所以我也是使用了在一台PC机上使用Vmware Workstation的方式来进行实验.总体结构是在PC机上安 ...

  8. 高级C#

    使用delegates委托写插件方法: public delegate int Transformer (int x); public class Util { public static void ...

  9. oc语言学习之基础知识点介绍(一):OC介绍

      一.第一个OC程序 #import <Foundation/Foundation.h> //导入头文件 int main(int argc, const char * argv[]) ...

  10. OpenID说明

    OpenID使用手册 摘要: OpenID是一种开放.离散式的用于用户数字标识的开源框架.在网络应用日益充斥的今天,作为终端用户的我们不得不在每个网站上设置帐号,并管理众多的帐号.而采用OpenID技 ...