/* ------------------------------------------------------------------- * FUNCTION: Insert * * Insert string s at index i. * * Time Complexity: O(logN) * ------------------------------------------------------------------- */ public void Insert(string s, int i) { Rope S = new Rope(s); if (i >= TotalLength) // add s to end { Concatenate(S); } else if (i <= 0) // add s to beginning { S.Concatenate(this); root = S.root; } else // split rope { Rope R2 = Split(i); Concatenate(S); Concatenate(R2); } }
/* ------------------------------------------------------------------- * FUNCTION: Split * * Splits a rope into two at index i, returns second rope. * * Time Complexity: O(logN) * ------------------------------------------------------------------- */ public Rope Split(int i) { if (i == 0) // no split, return copy of original rope { return(this); } Rope R2 = new Rope(""); // rope to be returned Rope Rtemp = new Rope(""); // temp - used for concatenation to R2 Node p = NodeAt(ref i); // find leaf node containing i Node cur; // used to traverse up tree if (p != null) { if (i > 0) // i is not at start of node { // split p into two nodes p.left = new Node() { value = p.value.Substring(0, i), parent = p, length = p.value.Substring(0, i).Length }; p.right = new Node() { value = p.value.Substring(i), parent = p, length = p.value.Substring(i).Length }; p.value = null; p.length = p.left.length; p = p.right; // set p to right child } // move up tree until you're at a right child or root while (p != root && p == p.parent.left) { p = p.parent; } cur = p.parent; // keep track of parent node p.parent = null; // remove link to parent R2.root = p; // set p to root of new rope cur.right = null; // cut off node p // move up tree until you have a new right child while (cur != root && cur == cur.parent.right) { cur = cur.parent; } cur = cur.parent; // continue cutting off right children while (cur != null && cur.right != null) { cur.right.parent = null; Rtemp.root = cur.right; R2.Concatenate(Rtemp); cur.right = null; // stop loop at right child of root or at root if (cur != root.right && cur != root) { // find new right child while (cur != root && cur == cur.parent.right) { cur = cur.parent; } if (cur == root) { cur = null; } } } ReBalance(); // Rebalance the tree starting from root } return(R2); }