Google B-Tree的使用demo

822 阅读2分钟

B树中的一些概念

image.png

  • m/2向上取整
  • 通常我们说m阶的B树,是指最多的子节点树;最少3阶,上图4阶
  • 根的子节点个数 2 <= M <=m 元素个数 1<= K <=m-1
  • 内部子节点个数m/2 <= M <=m 元素个数 m/2-1<= K <=m-1
  • 叶子节点 元素个数 m/2-1<= K <=m-1

B+树的限制

image.png

  • 非叶子节点只存储索引,数据都放在叶子节点中,叶子节点含所有数据
  • 所有叶子节点是一个链表
  • 非叶子节点的关键字的个数与其子树的个数相同;不像B树,子树的个数总比关键字个数多1个

B+树的优点

  • 每次查询稳定,深度相同都会到子节点
  • 树叶⼦节点存储了所有数据并且进⾏了排序,并且叶⼦节点之间有指针,可以很好的支持全表扫描,范围查找
  • B+树更适合外部存储。由于内节点无 data 域,每个节点能索引的范围更大更精确;非叶子节点都只是索引值,没有实际的数据,这就是B+树在一次IO里面,能读出的索引值更多。从而减少查询时候需要的IO次数!

google的B树go实现btree

基本操作

函数功能
Len获取长度
Min获取最小对象
Max获取最大对象
Has判断对象是否存在
Get获取对象,若不存在返回nil
Clone返回当前树的一个副本
Delete删除指定对象
DeleteMax删除最大对象
DeleteMin删除最小对象
Clear清空树
ReplaceOrInsert替换或者插入,如果是已经存在的则返回原始对象

迭代器操作

函数功能
Ascend升序迭代获取整个树
AscendGreaterOrEqual升序获取大于等于[a,+∞)
AscendLessThan升序获取小于(-∞,b)
AscendRange升序获取范围[a,b)
Descend降序迭代获取整个树
DescendGreaterOrEqual降序获取大于等于[a,+∞)
DescendLessThan降序获取小于(-∞,b)
DescendRange降序获取范围[a,b)

使用DEMO

import (
	"fmt"
	"strconv"

	"github.com/google/btree"
)

type Book struct {
	Code int
	Name string
}

func (b *Book) Less(item btree.Item) bool {
	if v, ok := item.(*Book); ok {
		return b.Code < v.Code
	}

	fmt.Println("Error: not valid item")
	return false
}

func testAddSearch() {
	tree := btree.New(3) //初始3阶Btree
	for i := 0; i < 100; i++ {
		//插入数据
		tree.ReplaceOrInsert(&Book{Code: i, Name: "freedom" + strconv.Itoa(i)})
	}

	//范围查找
	tree.DescendRange(&Book{Code: 50}, &Book{Code: 48}, func(a btree.Item) bool {
		item := a.(*Book)
		fmt.Println(item)
		return true
	})

	//降序遍历
	tree.Ascend(btree.ItemIterator(func(a btree.Item) bool {
		item := a.(*Book)
		fmt.Println(item)
		return true
	}))

	//升序遍历
	tree.Descend(btree.ItemIterator(func(a btree.Item) bool {
		item := a.(*Book)
		fmt.Println(item)
		return true
	}))

}

func main() {
	testAddSearch()
}