// starting at given node rotates it upwards until it reaches root private SplayTreeNode <T> Splay(SplayTreeNode <T> root) { if (root.parent == null) { return(root); } if (root.parent.parent == null) { return(root.parent.left == root?RotateLeftLeft(root.parent) : RotateRightRight(root.parent)); } if (root.parent.parent.left == root.parent) { return(root == root.parent.parent.left.left ? Splay(RotateLeftLeft(RotateLeftLeft(root.parent.parent))) : Splay(RotateLeftRight(root.parent.parent))); } return(root == root.parent.parent.right.right ? Splay(RotateRightRight(RotateRightRight(root.parent.parent))) : Splay(RotateRightLeft(root.parent.parent))); }
// private find, if current node is null return false,if current node is item return true // if current node is greater than item call find on left subtree, if lesser call find on right subtree // if item is found, splay node to root private bool Find(T item, SplayTreeNode <T> root) { if (root == null) { return(false); } else if (item.CompareTo(root.value) == 0) { this.root = Splay(root); return(true); } else if (item.CompareTo(root.value) < 0) { return(Find(item, root.left)); } else { return(Find(item, root.right)); } }
// Deletes given node private SplayTreeNode <T> DeleteNode(SplayTreeNode <T> root) { // if node has no children simply delete if (root.left == null && root.right == null) { return(null); } // if node has only one child replace it with child if (root.right == null) { root.left.parent = root.parent; return(root.left); } if (root.left == null) { root.right.parent = root.parent; return(root.right); } // if node has 2 children replace with next smallest node return(ReplaceNode(root)); }
// in order traversal, returns a string containing all elements // implemented making use of the parent nodes to test their functionality public string ParentTraverse() { SplayTreeNode <T> current = root; SplayTreeNode <T> previous; string output = ""; if (current == null) { return(output); } // loops until returning to root from the right or from left if there is no right branch do { // moves to furthest left child of current and adds its value to output, sets previous to current while (current.left != null) { current = current.left; } previous = current; output += current.value + " "; // traverses parent nodes until reaching a node with an unvisited right node or reaching the root while ((current.right == null || current.right == previous) && current.parent != null) { // sets previous to current then sets current to parent and adds value to output if previous was not on right side previous = current; current = current.parent; if (current.right != previous) { output += current.value + " "; } } // if there is an unvisited branch to the right, moves current to right if (current.right != previous && current.right != null) { current = current.right; } } while (current.parent != null); return(output); }
//private insert, takes a node and item and attempts to insert at that node // if node is not empty recurses on left/right node if item is smaller/larger than item at current position private SplayTreeNode <T> Insert(SplayTreeNode <T> root, T item, out SplayTreeNode <T> inserted) { if (root == null) { root = new SplayTreeNode <T>(); root.value = item; inserted = root; } // insertion logic, if the value (v )is < root, insert to the root.left // otherwise it's >=, so insert to the right // connects node to parent after else if (item.CompareTo(root.value) < 0) { root.left = Insert(root.left, item, out inserted); root.left.parent = root; } else { root.right = Insert(root.right, item, out inserted); root.right.parent = root; } return(root); }
// rotates right child to right ,then current to left public SplayTreeNode <T> RotateRightLeft(SplayTreeNode <T> root) { root.right = RotateLeftLeft(root.right); return(RotateRightRight(root)); }