package com.interview.tree; /** * http://www.geeksforgeeks.org/b-tree-set-1-insert-2/ * http://www.geeksforgeeks.org/b-tree-set-1-introduction-2/ */ public class BTree { private BTreeNode root = null; private static int T = 2; public void insert(int data){ if(root == null){ root = BTreeNode.newNode(data); return; } SplitResult sr = insert(root,data); if(sr != null){ BTreeNode newRoot = BTreeNode.newNode(); newRoot.n = 1; newRoot.isLeaf = false; newRoot.keys[0] = sr.c; newRoot.child[0] = sr.r1; newRoot.child[1] = sr.r2; root = newRoot; } } public boolean search(int data){ return search(root,data); } public boolean search(BTreeNode root, int data){ int i =0; while(i < root.n && root.keys[i] < data){ i++; } if(i < root.n && root.keys[i] == data){ return true; } if(root.isLeaf){ return false; } return search(root.child[i],data); } private SplitResult insert(BTreeNode root,int data){ if(root.isLeaf){ if(!root.isFull()){ root.insertKey(data, null, null); return null; }else{ SplitResult sr = splitNode(root,data,null,null); return sr; } }else{ int i=0; for(; i < root.n; i++){ if(data <= root.keys[i]){ SplitResult sr = insert(root.child[i],data); if(sr == null){ return null; }else{ if(!root.isFull()){ root.insertKey(sr.c, sr.r1, sr.r2); return null; }else{ SplitResult sr1 = splitNode(root,sr.c,sr.r1,sr.r2); return sr1; } } } } if(i == root.n){ SplitResult sr = insert(root.child[i],data); if(sr == null){ return null; }else{ if(!root.isFull()){ root.insertKey(sr.c, sr.r1, sr.r2); return null; }else{ SplitResult sr1 = splitNode(root,sr.c,sr.r1,sr.r2); return sr1; } } } } return null; } private SplitResult splitNode(BTreeNode node,int data, BTreeNode nr1, BTreeNode nr2){ int c = node.keys[node.n/2]; BTreeNode r1 = BTreeNode.newNode(); BTreeNode r2 = BTreeNode.newNode(); r1.n = node.n/2; r2.n = node.n - node.n/2-1; if(!node.isLeaf){ r1.isLeaf = false; r2.isLeaf = false; } int i=0; for(; i < node.n/2; i++){ r1.keys[i] = node.keys[i]; r1.child[i] = node.child[i]; } r1.child[i] = node.child[i]; i = node.n/2 + 1; int j=0; for(;i < node.n; i++,j++){ r2.keys[j] = node.keys[i]; r2.child[j] = node.child[i]; } r2.child[j] = node.child[i]; if(data < c){ r1.insertKey(data, nr1, nr2); }else{ r2.insertKey(data, nr1, nr2); } SplitResult sr = new SplitResult(); sr.c = c; sr.r1 = r1; sr.r2 = r2; return sr; } class SplitResult{ BTreeNode r1; BTreeNode r2; int c; } public void traverse(){ traverse(root); } private void traverse(BTreeNode root){ for(int i=0; i < root.n; i++){ if(!root.isLeaf){ traverse(root.child[i]); } System.out.print(root.keys[i] + " "); } if(!root.isLeaf){ traverse(root.child[root.n]); } } static class BTreeNode{ int n ; BTreeNode[] child = new BTreeNode[2*T]; int keys[] = new int[2*T-1]; boolean isLeaf; public void insertKey(int data,BTreeNode r1,BTreeNode r2){ int i = n-1; while(i >=0 && data < keys[i]){ keys[i+1] = keys[i]; i--; } keys[i+1] = data; int j = n; while(j > i+1){ child[j+1] = child[j]; j--; } child[j] = r1; child[j+1] = r2; n++; } public static BTreeNode newNode(int data){ BTreeNode node = new BTreeNode(); node.keys[0] = data; node.isLeaf = true; node.n = 1; return node; } public static BTreeNode newNode(){ BTreeNode node = new BTreeNode(); node.isLeaf = true; node.n = 0; return node; } public boolean isFull(){ return 2*T - 1 == n; } } public static void main(String args[]){ BTree bTree = new BTree(); bTree.insert(5); bTree.insert(4); bTree.insert(3); bTree.insert(2); bTree.insert(1); bTree.insert(6); bTree.insert(11); bTree.insert(13); bTree.insert(8); bTree.insert(7); bTree.insert(10); bTree.insert(9); bTree.insert(28); bTree.insert(22); bTree.insert(12); bTree.insert(18); bTree.insert(16); bTree.traverse(); System.out.print(bTree.search(28)); System.out.print(bTree.search(11)); System.out.print(bTree.search(5)); System.out.print(bTree.search(21)); System.out.print(bTree.search(3)); System.out.print(bTree.search(4)); System.out.print(bTree.search(14)); } }