/*This function recieves value from user and add it into the tree then * compare the depth of the tree with logbase3/2(n) if depth exceeded the * log value then scapegoat node is found and rebuild the tree rooted at * scapegoat node*/ public void add(double x) { Snode u = new Snode(x); int d = AddDepth(u); Console.WriteLine("Inserted {0}", x); Console.WriteLine("n={0}\tq= {1}\td={2}", n, q, d); double z = logBase32(q); Console.WriteLine("LogBase 2/3(q) ={0}", z); Console.WriteLine(); Console.WriteLine("____________"); if (d > logBase32(q)) { Console.WriteLine("Depth exceeded"); Console.WriteLine("Finding ScapeGoat Node"); Console.WriteLine("Rebuliding tree rooted at ScapeGoat Node"); Snode w = u.parent; while (3 * size(w) <= 2 * size(w.parent)) { w = w.parent; } rebuild(w.parent); } }
/* Provides Predecessor*/ public Snode Predecessor(Snode node) { if (node == null) { return(null); } return(Maximum(node.left)); }
/* Provides Successor*/ public Snode Successor(Snode node) { if (node == null) { return(null); } return(Minimum(node.right)); }
private void inorder(Snode node) { if (node != null) { inorder(node.left); Console.WriteLine(node.value + " "); inorder(node.right); } }
/*Convert bst to array*/ private int packintoarray(Snode u, Snode[] a, int i) { if (u == null) { return(i); } i = packintoarray(u.left, a, i); a[i++] = u; return(packintoarray(u.right, a, i)); }
/* Function to add values. * This function also provides the depth of the tree.*/ private int AddDepth(Snode u) { Snode w = root; if (w == null) { root = u; n++; q++; return(0); } bool done = false; int d = 0; do { if (u.value < w.value) { if (w.left == null) { w.left = u; u.parent = w; done = true; } else { w = w.left; } } else if (u.value > w.value) { if (w.right == null) { w.right = u; u.parent = w; done = true; } else { w = w.right; } } else { return(-1); } d++; }while (!done); n++; q++; return(d); }
/*This function call the delete function and then check if * tree is balanced or not. If tree is not balanced then it * rebuild the whole tree from root*/ public void Delete(double e) { root = Delete(root, e); if (root != null) { n--; Console.WriteLine("Value of n after deletion :: " + n); if (2 * n < q) { rebuild(root); q = n; } } }
/*Function to count the size of current node recursively*/ private int size(Snode u) { if (u == null) { return(0); } else { int l = 1; l = l + size(u.left); l = l + size(u.right); return(l); } }
/*Find maximum node from the tree*/ public Snode Maximum(Snode node) { if (node == null) { return(null); } if (node.right == null) { return(node); } else { return(Maximum(node.right)); } }
/* Find minimum node from the tree*/ public Snode Minimum(Snode node) { if (node == null) { return(null); } if (node.left == null) { return(node); } else { return(Minimum(node.left)); } }
/*Uses BST rule to delete any node from the Scapegoat tree*/ private Snode Delete(Snode node, double e) { if (node == null) { return(null); } if (node.value == e) { if (node.left == null && node.right == null) { return(null); } if (node.left != null && node.right == null) { return(node.left); } if (node.right != null && node.left == null) { return(node.right); } if (node.right != null) { Snode succ = Successor(node); node.value = succ.value; node.right = Delete(node.right, succ.value); } else { Snode pred = Predecessor(node); node.value = pred.value; node.left = Delete(node.left, pred.value); } return(node); } if (e < node.value) { node.left = Delete(node.left, e); } else { node.right = Delete(node.right, e); } return(node); }
private double Search(Snode node, double e) { if (node == null) { return(-1); } if (node.value == e) { return(node.value); } if (e < node.value) { return(Search(node.left, e)); } else { return(Search(node.right, e)); } }
/*Function to rebuild a tree rooted at Scapegoat node*/ private void rebuild(Snode u) { int ns = size(u); Snode p = u.parent; Snode[] a = new Snode[ns]; packintoarray(u, a, 0); if (p == null) { root = BuildBalanced(a, 0, ns); root.parent = null; } else if (p.right == u) { p.right = BuildBalanced(a, 0, ns); p.right.parent = p; } else { p.left = BuildBalanced(a, 0, ns); p.left.parent = p; } }
/*Constructor to intialize root 'q' and 'n'*/ public ScapeGoat() { root = null; n = 0; q = 0; }