记录一个半成品的B树Java实现

534 阅读2分钟

'

//写一次B树的实现 /*

  • 操作:1.创建一颗B树

  •  2.向B树中添加元素
    
  •  3.查找
    
  •  4.删除元素
    
  • B树特点:节点分为两种:叶子节点 非叶子节点

  • 叶子节点:存储只存储索引

  • 非叶子节点:存储索引和下面节点的指针 *插入:先找到该节点应该插入的位置,然后再尝试插入,可以看作是对一个节点的插入,如果该节点已经满了

  • 则先分裂,生成两个子节点,和一个中间索引,将中间索引插入到上层节点中,然后两个分裂的儿子作为两个结果插入到上层

  • 注:B树可以自平衡,删除节点的时候会自动调整,当左边和右边都可以自平衡,优先选择左边自平衡

  • */ public class B_Tree {

    B_TreeNode root; B_Tree(){ root=new B_TreeNode(); }

    public static final int MAX_DGREE = 5;

    static class Entry{ int key; int value; Entry(int key,int value){ this.key=key; this.value=value; } } //定义B树的节点 static class B_TreeNode{ B_TreeNode predecessor;//指向该节点的父亲节点 int cur_index_count;//当前节点中索引的个数,节点个数+1=最大度数(MAX_DEGREE) B_TreeNode[] successors;//B 树的儿子节点们 Entry[] indexs;//该节点的索引们 B_TreeNode(){ this.predecessor = null; this.cur_index_count=0; this.successors= new B_TreeNode[MAX_DGREE]; this.indexs = new Entry[MAX_DGREE-1]; } }

    //创建一颗B树,也就是创建一个B树的空节点 public B_TreeNode buildB_Tree(){ B_TreeNode b_treeNode = new B_TreeNode(); b_treeNode.cur_index_count=0; b_treeNode.indexs=new Entry[MAX_DGREE-1]; b_treeNode.successors = new B_TreeNode[MAX_DGREE]; return b_treeNode; }

    //向一个B树的节点中插入元素 public B_TreeNode insert_to_node(B_TreeNode b_treeNode,int key,int value){//返回头节点 //首先找到应该插入的位置 int position = 0; while(position<b_treeNode.cur_index_count&&b_treeNode.indexs[position].key<key){ position++; if(position>=b_treeNode.cur_index_count){ break; } } if(b_treeNode.cur_index_count>=MAX_DGREE-1){//该节点放不下了,要分裂 B_TreeNode left = new B_TreeNode(); B_TreeNode right = new B_TreeNode(); B_TreeNode predecessor = b_treeNode.predecessor;//该节点的父节点 if(predecessor==null){ predecessor=new B_TreeNode(); } int divide = MAX_DGREE/2; int index = 0; while(index<divide){//将索引分裂 insert_to_node(left,b_treeNode.indexs[index].key,b_treeNode.indexs[index].value); left.successors[index]=b_treeNode.successors[index]; index++; } index++; int index_right = 0; while(index<=MAX_DGREE-2){ insert_to_node(right,b_treeNode.indexs[index].key,b_treeNode.indexs[index].value); right.successors[index_right]=b_treeNode.successors[index]; index++; index_right++; } left.predecessor=predecessor; right.predecessor=predecessor; insert_to_node(predecessor,b_treeNode.indexs[divide].key,b_treeNode.indexs[divide].value); if(position<divide){ insert_to_node(left,key,value); } else{ insert_to_node(right,key,value); } predecessor.successors[predecessor.cur_index_count-1]=left; predecessor.successors[predecessor.cur_index_count]=right; return predecessor; } else{//不用分裂,直接将该索引插入即可 b_treeNode.indexs[position]=new Entry(key,value); b_treeNode.cur_index_count++; return b_treeNode; } }

    public int get(B_TreeNode root,int target){ if(root==null){ return -1; } int position =0; while(position++<=root.cur_index_count-1&&root.indexs[position].key<target){ if(root.indexs[position].key==target){ return root.indexs[position].value; } position++; } return get(root.successors[position],target); } public B_TreeNode search(B_TreeNode root,int target){ if(root==null){ return null; } int position = 0; while(position<=root.cur_index_count-1&&root.indexs[position].key<target){ if(root.indexs[position].key==target){ return root; } position++; } return search(root.successors[position],target); } public void put(B_TreeNode root,int key,int value){ B_TreeNode b_treeNode = search(root,key); //先找到 if(b_treeNode==null){ B_TreeNode nodeToInsert = node_to_insert(root,key); this.root=insert_to_node(nodeToInsert,key,value); while(root.predecessor!=null){ this.root= this.root.predecessor; } return; } insert_to_node(b_treeNode,key,value); }

    public B_TreeNode node_to_insert(B_TreeNode node,int target){ //找到一个节点 int position = 0; while(position<node.cur_index_count&&node.indexs[position++].key<target){ position++; } if(node.successors[position]==null){ return node; } else{ return node_to_insert(node.successors[position],target); } }

    public boolean delete(B_TreeNode root,int target){ //首先找到该节点所在位置 B_TreeNode b_treeNode = search(root,target); if(b_treeNode==null){ return false; } //先删除 int position = 0; while(b_treeNode.indexs[position].key!=target){ position++; } while(position+1<=b_treeNode.cur_index_count-1){ b_treeNode.indexs[position]=b_treeNode.indexs[position+1];// } B_TreeNode predecessor = b_treeNode.predecessor; /* //看是否需要调整,可以平衡条件:左边和右边索引数目相差>=2; int pre_position = 0; while(predecessor.successors[position++]!=b_treeNode){ pre_position++; } B_TreeNode left = predecessor.successors[pre_position-1]; B_TreeNode right = predecessor.successors[pre_position+1]; if(Math.abs(left.cur_index_count-b_treeNode.cur_index_count)>=2){

      }
      */
      return true;
    

    }

    public static void main(String[] args) { B_Tree b_tree = new B_Tree(); b_tree.put(b_tree.root,1,100); b_tree.put(b_tree.root,2,200); b_tree.put(b_tree.root,3,300); b_tree.put(b_tree.root,4,400); b_tree.put(b_tree.root,5,500); } //向右边移动 //direction = 0 表示向右边跳转 //向左边移动

}

'