package com.source;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Random;
//定义B树结构
@SuppressWarnings("hiding")
public class MyBTree{
private static final int DEFAULT_T = 2;
// B树根节点
private BTNoderoot;
// 度数
private int t;
// 非根节点的最少关键字个数
private int minKeyNum;
// 非根节点的最大关键字个数
private int maxKeyNum;
// 定义树节点
private class BTNode{
// 关键字个数
public int n = 0;
// 存放关键字
public Listkeys = new
ArrayList(maxKeyNum);
// 存放孩子节点的指针
public List> children = new ArrayList>(
maxKeyNum + 1);
// 是否为叶子节点,初始化是叶子节点
public boolean isLeaf = true;
// 向树节点中插入元素
public void insertKey(int index, Object key) {
keys.add(index, key);
n++;
if (keys.size() > maxKeyNum) {
keys.remove(maxKeyNum);
}
}
// 在树节点中移除元素
public Object removeKey(int index) {
Object key = keys.remove(index);
n--;
return key;
}
// 添加孩子节点指针
public void insertChild(int index, BTNodechild)
{
children.add(index, child);
if (children.size() > maxKeyNum + 1) {
children.remove(maxKeyNum + 1);
}
}
// 移除孩子节点指针
public BTNoderemoveChild(int index) {
BTNodechild = children.remove(index);
return child;
}
}
public MyBTree() {
this(DEFAULT_T);
}
public MyBTree(int degree) {
if (degree < 2) {
t = DEFAULT_T;
}
this.t = degree;
this.minKeyNum = degree - 1;
this.maxKeyNum = 2 * degree - 1;
BTNodenode = new
BTNode();
this.root = node;
}
// 添加元素
public void insert(Object key) {
BTNoder = root;
// 若节点元素已满
if (root.n == maxKeyNum) {
BTNodenewRoot = new
BTNode();
root = newRoot;
newRoot.isLeaf = false;
// 添加原节点为孩子节点
newRoot.insertChild(0, r);
// 分裂孩子节点
sliptChild(newRoot, 0);
insertNoFull(newRoot, key);
} else
insertNoFull(r, key);
}
// 分裂节点
private void sliptChild(BTNodex, int index)
{
// 新增结点
BTNodenewNode = new
BTNode();
// 获取原父节点
BTNodey = x.children.get(index);
// 标记是否为叶子节点
newNode.isLeaf = y.isLeaf;
// 向新节点添加元素
for (int j = 0; j < minKeyNum; j++) {
// 从最小元素个数处开始添加
newNode.insertKey(j, y.keys.get(j + t));
}
// 如果原父节点不是叶子节点
if (!y.isLeaf) {
for (int j = 0; j < t; j++) {
newNode.insertChild(j, y.children.get(j + t));
}
}
// 修改节点元素个数
newNode.n = minKeyNum;
y.n = minKeyNum;
// 链接新节点
x.insertChild(index + 1, newNode);
// 添加新元素
x.insertKey(index, y.keys.get(minKeyNum));
}
// 将元素添加至未满的树节点中
private void insertNoFull(BTNodex, Object key)
{
int i = x.n - 1;
// 是叶子节点
if (x.isLeaf) {
while (i >= 0 && key.hashCode() <
x.keys.get(i).hashCode())
i--;
x.insertKey(i + 1, key);
} else {
// 非叶子节点,寻找添加位置
while (i >= 0 && key.hashCode() <
x.keys.get(i).hashCode())
i--;
i = i + 1;
// 若添加位置处元素已满,则分裂节点
if (x.children.get(i).n == maxKeyNum) {
sliptChild(x, i);
// 关键值大于分裂的一个节点
if (key.hashCode() > x.keys.get(i).hashCode())
i = i + 1;
}
insertNoFull(x.children.get(i), key);
}
}
// 删除元素
public boolean delete(Object key) {
return delete(root, key) != null ? true : false;
}
//从某个节点开始删除元素
private Object delete(BTNodex, Object key)
{
// 该过程需要保证,对非根节点执行删除操作时,其关键字个数至少为t。
// 获取节点的元素个数
int n = x.n;
// 断言机制,判断是否正确执行
assert n >= t || x == root;
int i = 0;
while (i < n && key.hashCode() >
x.keys.get(i).hashCode())
i++;
// 当前节点等于要删除的节点
if (i < n && key.equals(x.keys.get(i))) {
// 当前节点是叶子节点
if (x.isLeaf) {
// 直接删除关键字
x.removeKey(i);
}
else {
//获取两边子树根节点
BTNodelittle = x.children.get(i);
BTNodebigger = x.children.get(i + 1);
//左边节点个数满足度数要求
if (little.n >= t) {
// 小于关键值最大值
Object preKey = deleteMaxKey(little);
x.keys.set(i, preKey);
}
else if (bigger.n >= t) {
// 大于关键字最小值
Object nextKey = deleteMinKey(bigger);
x.keys.set(i, nextKey);
}
else {
// 合并节点
int ySize = little.n;
int zSize = bigger.n;
// little.insertKey(ySize, key);
// ySize++;
boolean isChildLeaf = little.isLeaf;
for (int j = 0; j < zSize; j++) {
// 大于关键字子树。添加到小于关键字的子树
little.insertKey(ySize, bigger.keys.get(j));
// 若不是叶节点,则添加孩子节点
if (!isChildLeaf) {
little.insertChild(ySize, bigger.children.get(j));
}
ySize++;
}
//若不是叶节点,添加最后一个指向孩子的指针
if (!isChildLeaf) {
little.insertChild(ySize, bigger.children.get(zSize -
1));
}
//删除节点以及对应的子节点
x.removeKey(i);
x.removeChild(i + 1);
if (x.n == 0) {
root = little;
}
// delete(little, key);
}
}
//删除节点成功
return key;
}
else if (x.isLeaf) {
// 没有找到该关键字,直接返回
return null;
}
// 当前节点不等于要删除的节点
else {
return delete(x.children.get(i), key);
}
}
//删除一个节点中最大的元素
private Object deleteMaxKey(BTNodex) {
int keyNum = x.n;
if (x.isLeaf) {
return x.removeKey(keyNum - 1);
}
else {
return delete(x,x.keys.get(x.n-1));
}
}
//删除一个节点中最小的元素
private Object deleteMinKey(BTNodex) {
//节点为叶节点
if (x.isLeaf) {
return x.removeKey(0);
}
else {
return delete(x,x.keys.get(0));
}
}
//是否包含某个元素
public boolean contains(Object object){
return contains(root, object);
}
// 从某节点开始是否包含某个元素
private boolean contains(BTNodebtnode,Object
object){
int index = findPosition(btnode, object, 0, btnode.n-1);
// 找到节点
if(btnode.keys.get(index).hashCode() ==
object.hashCode()){
System.out.println("Find \""+object+"\" at index -> "+
(index+1));
return true;
}
// 叶子节点,遍历结束
else if(btnode.isLeaf){
System.out.println("The BTree has no member values
\""+object+"\"!" );
return false;
}
// 非叶子节点
else if(btnode.keys.get(index).hashCode() <
object.hashCode()){
return contains(btnode.children.get(index+1),object);
}
else {
return contains(btnode.children.get(index),object);
}
}
//二分查找树节点
private int findPosition(BTNodebtnode,Object
object,int start,int end){
if(start >= end)
return start;
int middle = start+(end-start)/2;
if(btnode.keys.get(middle).hashCode() ==
object.hashCode())
return middle;
else if (btnode.keys.get(middle).hashCode() >
object.hashCode()) {
return findPosition(btnode, object, start, middle-1);
}
else {
return findPosition(btnode, object, middle+1, end);
}
}
// 返回B树中元素的个数
public int size(){
return count(root);
}
//统计某个节点下孩子个数
private int count(BTNodenode){
if(node.isLeaf)
return node.n;
int sum = node.n;
for(int index = 0;index <= node.n;++index){
sum += count( node.children.get(index) );
}
return sum;
}
//是否为空
public boolean isEmpty() {
if(root.n == 0)
return true;
return false;
}
//打印B树
public void print() {
int level = 0;
Deque> queue1 = new
ArrayDeque.BTNode>();
Deque> queue2 = new
ArrayDeque.BTNode>();
// 添加子节点
queue1.add(root);
while (!queue1.isEmpty() || !queue2.isEmpty()) {
//转移元素
if(queue1.isEmpty()){
level++;
while (!queue2.isEmpty()) {
queue1.add(queue2.poll());
}
}
System.out.format("Level_%d : ", level);
BTNodenode = queue1.poll();
for (int i = 0; i < node.n; i++) {
System.out.format("M",node.keys.get(i));
}
System.out.println();
//添加至下一层
if (!node.isLeaf) {
for (int i = 0; i < node.n + 1; i++) {
queue2.add(node.children.get(i));
}
}
}
}
public static void main(String[] args) {
MyBTree bTree = new MyBTree(20);
Random random = new Random();
for(int index = 0;index < 200;++index){
int temp = random.nextInt(128)+1;
bTree.insert(temp);
}
bTree.print();
System.out.println(bTree.size());
System.out.println(bTree.contains(77));
}
}