BTree的基本操作

package CH18;

import java.util.Spliterator;

import javax.enterprise.inject.New;

import CH18.Btree3.BTreeNode;
import sun.net.www.content.text.plain;

public class BTREE<Key extends Comparable<Key>, Value> {

	// m阶,节点最多M个,关键字最多M-1
	private static int MAX_CHILDS_NUM = 5;
	// 节点最少MIN_KEY_NUM个,关键字最少MIN_KEY_NUM
	private static int MIN_CHILDS_NUM = (int) Math.ceil(MAX_CHILDS_NUM / 2.0);

	private static int MIN_KEYS_NUM = MIN_CHILDS_NUM - 1;

	private static int MAX_KEYS_NUM = MAX_CHILDS_NUM - 1;

	private static int MIN_DELETE_KEY_NUM = MAX_CHILDS_NUM;

	private int height = 0;

	private Node root;

	private static class ReturnVo {
		private Node lt;
		private Node gt;
		private Entry data;

		public ReturnVo(Node lt, Node gt, Entry data) {
			super();
			this.lt = lt;
			this.gt = gt;
			this.data = data;
		}

	}

	private final static class Node {

		private Node parent;

		private int num;
		// 0号负责占位,留一个备用,M-1个为合理key
		private Entry[] datas = new Entry[MAX_KEYS_NUM + 2];

		public Node(int i) {
			num = i;
		}

		// 一个备用个为合理key
		Node[] childs = new Node[MAX_CHILDS_NUM + 1];

	}

	private static class Entry {

		private Comparable key;

		private Object value;

		public Entry(Comparable key, Object value) {
			super();
			this.key = key;
			this.value = value;
		}
	}

	private boolean eq(Comparable key1, Comparable key2) {
		return key1.compareTo(key2) == 0;
	}

	private boolean less(Comparable key1, Comparable key2) {
		return key1.compareTo(key2) < 0;
	}

	private boolean notlarger(Comparable key1, Comparable key2) {
		return key1.compareTo(key2) <= 0;
	}

	public void put(Key key, Value value) {
		System.out.println(key + "开始插入");
		Entry entry = new Entry(key, value);
		if (root == null) {
			root = new Node(1);
			root.childs = null;
			root.datas[1] = entry;
			return;
		}

		ReturnVo rootVo = insertEntry(root, entry, height);
		if (rootVo != null) {
			System.out.println(key + "需要分裂");
			root = new Node(1);
			root.datas[1] = rootVo.data;
			root.childs[0] = rootVo.lt;
			root.childs[1] = rootVo.gt;
			height++;
		}
		System.out.println(key + "完成插入");
	}

	public void remove(Node node, Comparable key, int hv) {
		int j = 1;
		while (j <= node.num) {
			if (notlarger(key, node.datas[j].key)) {
				break;
			}
			j++;
		}
		if (hv == 0) {
			if (eq(node.datas[j].key, key)) {
				deleteLeafnode(node, j);
			}else {
				System.out.println("没找到该值key:"+key);
			}
		}else {
			if(eq(node.datas[j].key, key)){
				deleteNonleafnode(node, j,hv);
				return;
			}
			boolean flag = (j-1 == node.num);
			
			if(node.childs[j-1].num<MIN_DELETE_KEY_NUM){
				fill(node,j-1,hv);
			}
			if (flag && j-1 > node.num)
				//fill里的向前合并起了作用,导致j需要调整,
				remove(node.childs[j-2], key, hv-1);
            else
            	remove(node.childs[j-1], key, hv-1);
			
		}
	}
	
	/**
	 * 借东西,
	 * @param node
	 * @param j
	 */
	private void fill(Node node, int j,int hv) {
		
		
		if(j>0&&node.childs[j-1].num>=MIN_DELETE_KEY_NUM){
			borrowFromPrev(node,j,hv);
		}else if(j<MAX_CHILDS_NUM-1&&node.childs[j+1].num>=MIN_DELETE_KEY_NUM){
			borrowFromNext(node, j, hv);
		}else if(node.num != j){
			merge(node,j,hv);
		}else {
			merge(node,j-1,hv);
		}
	}
	/**
	 * 兄弟间 合作,父节点减少一个key
	 * @param node
	 * @param i
	 * @param hv
	 * 
	 *  before:
	 *     node               child:c2              sibling:c3
	 * null|10|20|30|       null|15|18|             null|24|26|
	 *   c1|c2|c3|c4|         q1|q2|q3|               z1|z2|z3|
	 *   
	 * after:
	 *     node               child:c2                sibling:c3
	 * null|10|30|       null|15|18|20|24|26|            null
	 *   c1|c2|c4|        |q1|q2|q3|z1|z2|z3|               
	 * 
	 */
	private void merge(Node node, int j, int hv) {
		
		Node child = node.childs[j];
		Node sibling = node.childs[j+1];
		
		for(int l6=1;l6<=sibling.num;l6++){
			child.datas[MIN_DELETE_KEY_NUM+l6] = sibling.datas[l6];
		}
		child.datas[MIN_DELETE_KEY_NUM] = node.datas[j+1];
	    
		for(int ni=j+1;ni<node.num;ni++){
			node.datas[ni] = node.datas[ni+1]; 
		}
		node.datas[node.num]=null;
		
		
		if(hv>0){
			for(int l7=0;l7<=sibling.num;l7++){
				child.childs[MIN_DELETE_KEY_NUM+l7] = sibling.childs[l7];
			}
			for(int n2=j+1;n2<node.num;n2++){
				node.childs[n2] = node.childs[n2+1]; 
			}
			node.childs[node.num]=null;
		}
		if(hv == height){
			height--;
		}
		
		node.num--;
		child.num += sibling.num+1;
		
	}

	/**
	 * 真儿子找他的干哥哥借
	 * @param node
	 * @param j
	 * @param hv
	 * 
	 *	before:
	 *     node               child:c2                sibling:c3
	 * null|10|20|30|       null|15|18|             null|24|26|28|
	 *   c1|c2|c3|c4|         q1|q2|q3|               z1|z2|z3|z4|
	 *   
	 * after:
	 *     node               child:c2                sibling:c3
	 * null|10|24|30|       null|15|18|20|             null|26|28|
	 *   c1|c2|c3|c4|        |q1|q2|q3|z1|               z2|z3|z4|
	 * 
	 */
	private void borrowFromNext(Node node, int j, int hv) {
		
	   Node child = node.childs[j];
	   Node sibling = node.childs[j+1];
	   
	   child.datas[child.num+1] = node.datas[j+1];
	   
	   node.datas[j+1] = sibling.datas[1];
	   
		
	   for(int l3=1;l3<=child.num;l3++){
		   sibling.datas[l3-1] = sibling.datas[l3];
	   }
	   sibling.datas[child.num]=null;
	   
	   if(hv>0){
		   for(int l4=1;l4<=child.num;l4++){
			   sibling.childs[l4-1] = sibling.childs[l4];
		   }
		   sibling.childs[sibling.num]=null;
		   child.childs[child.num+1] = sibling.childs[0];
	   }
		
		
	}

	/**
	 * 真儿子找他的干弟弟借
	 * @param node
	 * @param j,child的位置
	 * @param hv
	 * 
	 * before:
	 *     node               child:c2                sibling:c1
	 * null|10|20|30|       null|15|18|             null|04|06|08|
	 *   c1|c2|c3|c4|         q1|q2|q3|               z1|z2|z3|z4|
	 *   
	 * after:
	 *     node               child:c2                sibling:c1
	 * null|08|20|30|       null|10|15|18|             null|04|06|
	 *   c1|c2|c3|c4|         z4|q1|q2|q3|               z1|z2|z3|
	 * 
	 */
	void borrowFromPrev(Node node,int j,int hv) {

        Node child = node.childs[j];
        Node sibling = node.childs[j-1];
              
        for(int l2=child.num;l2>0;l2--){
        	child.datas[l2+1] = child.datas[l2];
        }
        
        child.datas[1] = node.datas[j];
        
        node.datas[j]= sibling.datas[sibling.num];
        
        if(hv > 0){
        	for(int l3=child.num;l3>=0;l3--){
            	child.childs[l3+1] = child.childs[l3];
            }
        	child.childs[0] = sibling.childs[sibling.num];
        }
        
        child.num++;
        
        sibling.datas[sibling.num]=null;
        sibling.childs[sibling.num]=null;
        sibling.num--;
    }

	/**
	 * 删除叶子节点
	 * @param node
	 * @param j
	 */
	private void deleteLeafnode(Node node,int j){
		for (int l1 = j; l1 < node.num; l1++) {
			node.datas[l1] = node.datas[l1 + 1];
		}
		node.num--;
		node.datas[node.num]=null;
	}
	/**
	 * 删除非叶子节点
	 */
	private void deleteNonleafnode(Node node,int j,int hv){
		if(node.childs[j-1].num>=MIN_DELETE_KEY_NUM){
			Entry pred = getPred(node,j,hv);
			node.datas[j] = pred;
			remove(node.childs[j-1],pred.key, hv-1);
		}else if(node.childs[j].num>=MIN_CHILDS_NUM){
			Entry succ = getSucc(node,j,hv);
			node.datas[j+1] = succ;
			remove(node.childs[j],succ.key, hv-1);
		}else {
			merge(node, j-1, hv);
			remove(node.childs[j-1],node.datas[j].key, hv-1);
		}
	}

	private Entry getSucc(Node node, int j, int hv) {
		Node cur = node.childs[j-1];
		hv--;
		while(hv!=0){
			cur = cur.childs[0];
			hv--;
		}
		return cur.datas[1];
	}

	private Entry getPred(Node node,int j,int hv) {
		Node cur = node.childs[j-1];
		hv--;
		while (hv!=0) {
			cur = cur.childs[cur.num];
			hv--;	
		}
		return cur.datas[cur.num];
	}

	private ReturnVo insertEntry(Node node, Entry entry, int hv) {
		int j = 1;
		while (j <= node.num) {
			if (less(entry.key, node.datas[j].key)) {
				break;
			}
			if (eq(entry.key, node.datas[j].key)) {
				node.datas[j].value = entry.value;
				return null;
			}
			j++;
		}
		// leaf
		if (hv == 0) {
			for (int l1 = node.num; l1 >= j; l1--) {
				node.datas[l1 + 1] = node.datas[l1];
			}
			node.datas[j] = entry;
			node.num++;
		} else {
			ReturnVo revo = insertEntry(node.childs[j - 1], entry, hv - 1);
			if (revo == null) {
				return null;
			}
			// 补上下层传来的child指向的变更和entry
			for (int k1 = node.num; k1 >= j; k1--) {
				node.childs[k1 + 1] = node.childs[k1];
				node.datas[k1 + 1] = node.datas[k1];
			}
			node.childs[j - 1] = revo.lt;
			node.childs[j] = revo.gt;
			node.datas[j] = revo.data;
		}

		if (node.num > MAX_KEYS_NUM) {

			return split(node);
		} else {
			return null;
		}

	}

	// 包含需提升至父节点的entry
	private ReturnVo split(Node h) {
		Node lt = new Node(MIN_KEYS_NUM);
		Node gt = new Node(MIN_KEYS_NUM);

		/*
		 * null|02|10|20|30|50| --->null|02|10| + null|30|50| E1|E2|E3|E4|E5|E6|
		 * E1|E2|E3| E4|E5|E6|
		 */

		System.arraycopy(h.datas, 1, lt.datas, 1, MIN_KEYS_NUM);
		System.arraycopy(h.datas, MIN_KEYS_NUM + 2, gt.datas, 1, MIN_KEYS_NUM);

		if (h.childs != null) {
			System.arraycopy(h.childs, 0, lt.childs, 0, MIN_CHILDS_NUM);
			System.arraycopy(h.childs, MIN_CHILDS_NUM, gt.childs, 0, MIN_CHILDS_NUM);
		}

		ReturnVo vo = new ReturnVo(lt, gt, h.datas[MIN_KEYS_NUM + 1]);
		return vo;

	}

	public static void main(String[] args) {
		BTREE<Integer, Integer> btree = new BTREE<Integer, Integer>();
		btree.put(1, 1);
		btree.put(11, 11);
		btree.put(8, 8);
		btree.put(10, 10);
		btree.put(12, 12);
		btree.put(9, 9);
		btree.put(2, 2);
		btree.put(3, 3);
		btree.put(6, 6);
		btree.put(1, 1);
		btree.put(4, 4);
	}

}

猜你喜欢

转载自blog.csdn.net/zharen351991/article/details/80136512